日曜技術者のメモ

趣味でやった事のメモ書きです。

SystemVerilogのパラメータ付きクラスを試してみた(解決編)

SystemVerilogのパラメータ付きクラスを試してみたを更新してから
Twitterで「Baseクラス作ったらpushできる」と教えて頂き解決しました。

修正したコード

module top();

class c_hoge_base; //Baseクラス追加
  
  virtual function void print(); 
  endfunction
  
endclass

//Baseクラス継承
class c_hoge #(int k = 0) extends c_hoge_base; 

  function void print(); //Warning対策にvoidを追加
    $display("k = %d",k);
  endfunction
  
endclass:c_hoge

//型をBaseクラスにする
c_hoge_base q_c_hoge[$];
c_hoge_base h_c_hoge[*];
c_hoge_base i_c_hoge_base;

initial begin
  c_hoge#(0) i0_c_hoge;
  c_hoge#(1) i1_c_hoge;
  c_hoge#(2) i2_c_hoge;
  c_hoge#(3) i3_c_hoge;
  
  i0_c_hoge = new();
  i1_c_hoge = new();
  i2_c_hoge = new();
  i3_c_hoge = new();
  
  i0_c_hoge.print();
  i1_c_hoge.print();
  i2_c_hoge.print();
  i3_c_hoge.print();

  q_c_hoge.push_back(i0_c_hoge);
  h_c_hoge["hoge0"] = i0_c_hoge;

  q_c_hoge.push_back(i1_c_hoge);
  h_c_hoge["hoge1"] = i1_c_hoge;
  
  $display("pop_front");
  i_c_hoge_base = q_c_hoge.pop_front();
  i_c_hoge_base.print();
  i_c_hoge_base = q_c_hoge.pop_front();
  i_c_hoge_base.print();

  $display("hash table");
  h_c_hoge["hoge0"].print();
  
end
endmodule

実行結果

# k =           0
# k =           1
# k =           2
# k =           3
# pop_front
# k =           0
# k =           1
# hash table
# k =           0

これでパラメータ付きクラスでもキューや連想配列に入れる事が出来ました。
後、newの引数でいいじゃんというツッコミも頂いたので私の使用例を載せました。

このコードでやりたい事は

  • モジュールtest_modelをgenerateで複数インスタンス
  • test_model内にはtaskが宣言されていてこれをクラスから参照したい。
  • writeタスクは手が入れれないのでパス指定で呼び出すしかない。(writeタスクをクラスに移動できるならこんな事しなくても大丈夫ですが・・・)
  • できるだけループ宣言を使って記述を減らしたい(ただしこの例では減らせませんでした^^;

後、enum連想配列使ってクラス配列を任意の文字列で呼び出すのが
どのモデルにつながっているか見わかりやすくて好きなので使っています。

typedef enum {
  test_model_A,
  test_model_B,
  test_model_C,
  test_model_D,
  test_model_E
} e_model_name;

parameter MODEL_NUM = 5;

/*************test_module**************/
/*変更できないモデル*/
module test_model();
  task write(int a);
    $display("test_model write task %d",a);
  endtask
  
endmodule : test_model

/***************prg_top*****************/

module prg_top();
  class piyo_base;
    virtual task start();
    endtask
    
    virtual task exec();
    endtask
  endclass
  
  class piyo#(e_model_name k = test_model_A) extends piyo_base;
    int m_val;
    e_model_name m_e_model_name;
    
    function new(int val);
      m_val = val;
      m_e_model_name = k;
    endfunction
    
    task start();
      $display("start : This Class %s , m_val = %0d",m_e_model_name,m_val);
    endtask
    
    task exec();
      $display("exec : This Class %s , m_val = %0d",m_e_model_name,m_val);
      $root.top.model_loop[k].i_test_model.write(m_val);//ここのkはパラメータでないとダメ(変数は使えない)
    endtask
    
  endclass
  
  piyo_base piyo_h_array[e_model_name];
  
  piyo#(test_model_A) i_piyo0;
  piyo#(test_model_B) i_piyo1;
  piyo#(test_model_C) i_piyo2;
  piyo#(test_model_D) i_piyo3;
  piyo#(test_model_E) i_piyo4;        

  initial begin
    i_piyo0 = new(10);
    i_piyo1 = new(20);
    i_piyo2 = new(30);
    i_piyo3 = new(40);
    i_piyo4 = new(50);    

    piyo_h_array[test_model_A] = i_piyo0;
    piyo_h_array[test_model_B] = i_piyo1;
    piyo_h_array[test_model_C] = i_piyo2;
    piyo_h_array[test_model_D] = i_piyo3;
    piyo_h_array[test_model_E] = i_piyo4;    

    $display("\n-----start task-----");
    foreach (piyo_h_array[i]) begin
      piyo_h_array[i].start;
    end
    
    $display("\n-----exec task-----");
    piyo_h_array[test_model_B].exec;
    piyo_h_array[test_model_C].exec;
    
    $finish;
  end
  
endmodule:prg_top
    
/***************top*****************/

module top();
  generate
    genvar i;
    for(i=0; i<MODEL_NUM;i=i+1)begin : model_loop
      test_model i_test_model();
    end
  endgenerate
  
  prg_top i_prg_top();
endmodule : top

実行結果

# 
# -----start task-----
# start : This Class test_model_A , m_val = 10
# start : This Class test_model_B , m_val = 20
# start : This Class test_model_C , m_val = 30
# start : This Class test_model_D , m_val = 40
# start : This Class test_model_E , m_val = 50
# 
# -----exec task-----
# exec : This Class test_model_B , m_val = 20
# test_model write task          20
# exec : This Class test_model_C , m_val = 30
# test_model write task          30
# ** Note: $finish    : E:/altera/13.0/test/test2.sv(81)


i_piyo0~i_piyo4までの宣言をループ内に入れる事が出来ればもっと
コードが短くなると思いますがやり方が思いつきませんでした。

そもそもこんなやり方しなくてももっと良い方法があるかも・・・

7/4追記:

コメントで指摘してもらったdefineマクロで
i_piyo0~i_piyo4が簡潔にならないか試してみました。

//マクロ定義
`define PIYO_INSTANCE(val) piyo#(val``) i_piyo``val``;
`define PIYO_SET(val,init) i_piyo``val`` = new(init``); \
                           piyo_h_array[``val``] = i_piyo``val``;

//宣言(一部抜粋)
  `PIYO_INSTANCE(0) //piyo#(test_model_A) i_piyo0;
  `PIYO_INSTANCE(1) //piyo#(test_model_B) i_piyo1;
  `PIYO_INSTANCE(2) //piyo#(test_model_C) i_piyo2;
  `PIYO_INSTANCE(3) //piyo#(test_model_D) i_piyo3;
  `PIYO_INSTANCE(4) //piyo#(test_model_E) i_piyo4;

  initial begin

    `PIYO_SET(0,10)  //i_piyo0 = new(10); piyo_h_array[test_model_A] = i_piyo0;
    `PIYO_SET(1,20)  //i_piyo1 = new(20); piyo_h_array[test_model_B] = i_piyo1;
    `PIYO_SET(2,30)  //i_piyo2 = new(30); piyo_h_array[test_model_C] = i_piyo2;
    `PIYO_SET(3,40)  //i_piyo3 = new(40); piyo_h_array[test_model_D] = i_piyo3;
    `PIYO_SET(4,50)  //i_piyo4 = new(50); piyo_h_array[test_model_E] = i_piyo4;
	

ちょっと記述は少なくなったかな?
本当は↓の様にループで書ければ良かったのだが残念ながらエラーになりました。

  generate
    genvar j;
    for(j=0; j<MODEL_NUM;j=j+1)begin : model_loop
      `PIYO_INSTANCE(j)
    end
  endgenerate

SystemVerilogのパラメータ付きクラスを試してみた

[SystemVerilog] 接続記述をもっとエクストリーム的に書こうという記事で
パラメータがついたクラスが紹介されているので試してみた。

まずはパラメータが反映されているかテスト

module top();

class c_hoge #(int k = 0);
  
  function print();
    $display("k = %d",k);
  endfunction
  
endclass:c_hoge

initial begin
  c_hoge #(0)i0_c_hoge;
  c_hoge #(1)i1_c_hoge;
  c_hoge #(2)i2_c_hoge;
  c_hoge #(3)i3_c_hoge;
  
  i0_c_hoge = new();
  i1_c_hoge = new();
  i2_c_hoge = new();
  i3_c_hoge = new();
  
  i0_c_hoge.print();
  i1_c_hoge.print();
  i2_c_hoge.print();
  i3_c_hoge.print();
  
end
endmodule

ModelSimで実行すると

# k =           0
# k =           1
# k =           2
# k =           3

おぉ!ちゃんと入ってる!

で、私がやりたいのはこれをデータクラスとして使って
キューや連想配列に入れる事だったのだが・・・

エラーで動かなかった。書いたコードは↓

module top();

class c_hoge #(int k = 0);
  
  function print();
    $display("k = %d",k);
  endfunction
  
endclass:c_hoge

c_hoge q_c_hoge[$];
c_hoge h_c_hoge[*];
  
initial begin
  c_hoge#(0) i0_c_hoge;
  c_hoge#(1) i1_c_hoge;
  c_hoge#(2) i2_c_hoge;
  c_hoge#(3) i3_c_hoge;
  
  i0_c_hoge = new();
  i1_c_hoge = new();
  i2_c_hoge = new();
  i3_c_hoge = new();
  
  i0_c_hoge.print();
  i1_c_hoge.print();
  i2_c_hoge.print();
  i3_c_hoge.print();

  q_c_hoge.push_back(i0_c_hoge);
  h_c_hoge["hoge0"] = i0_c_hoge;

  q_c_hoge.push_back(i1_c_hoge); //ここでエラー
  h_c_hoge["hoge1"] = i1_c_hoge;
  
end
endmodule

実行

# k =           0
# k =           1
# k =           2
# k =           3
# ** Fatal: Illegal assignment to class work.top/c_hoge #(0) from class work.top/c_hoge #(1)
# 
#    Time: 0 ps  Iteration: 0  Process: /top/#INITIAL#14(#ublk#0#15) File: E:/altera/13.0/test/test.sv
# Fatal error in Module top at E:/altera/13.0/test/test.sv line 33
# 

パラメータが初期値(k=0)の時は問題無い様ですが
パラメータに値が入るとエラーになります。

多分キューや連想配列を宣言する時の型c_hogeはc_hoge#(0)と同じなので
c_hoge#(1)という型(?)が入らないと言う事かな?

C++のtemplate的な使い方を想定してたのだが・・・(´・ω・`)

7/3追記 : Twitterで色々教えて頂き解決しました。
SystemVerilogのパラメータ付きクラスを試してみた(解決編)

プログラミング言語? NyarukoでLet's\(・ω・)/にゃーしてみた-2-

前回の足し算は1桁しか表示出来なかったので2桁表示に改造してみた。
それが以下プログラム

adder2.nyaruko

(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃーcosmic!(」・ω・)」うー(/・ω・)/にゃーcosmic!(」・ω・)」うー!!(/・ω・)/にゃー!!
Let's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーLet's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃー
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!
(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーCHAOS☆CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃーCHAOS☆CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーI WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーCHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃーLet's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!I WANNA CHAOS!

しかし、このプログラム問題はない(はず)ですが実行しても動作しません。
これを元のBrainf**kで書いたコードが以下になります。

+++++++[>++++++>++++++++>+>+++++++<<<<-]>+>+++++>++>->,>,<
.<<<<.>>>>>.<<<<.>>
[>->->+<<<-]>
[>+<-]<
+<
[>>>[<]<[>>->>+<<<]<<-]>>>
[>[<+<<+>>>-]<<<.>>-.>]<<[>>>[>+<-]>.<<<]

これはBrainf**k系の処理系で実行する事ができて2桁表示も動作しています。
どうもr-fxxkの[]処理がBrainf**kとは異なる様です。
その為条件分岐を書くと挙動がおかしくなります。
書き換えれるか試しましたがRuby経験0の私には無理でしたorz

プログラミング言語? NyarukoでLet's\(・ω・)/にゃーしてみた-1-

Brainf**kを調べてたらnyarukoという言語を見つけたのでプログラミングしてみた。

https://github.com/masarakki/nyaruko_lang

命令は簡単。たった8つしかない。

(」・ω・)」うー(/・ω・)/にゃー - ポインタを右へ移動
(」・ω・)」うー!(/・ω・)/にゃー! - ポインタの指す値を1増やす
(」・ω・)」うー!!(/・ω・)/にゃー!! - ポインタを左へ移動
(」・ω・)」うー!!!(/・ω・)/にゃー!!! - ポインタの指す値を1減らす
CHAOS☆CHAOS! ポインタの指す値が0なら 対応する 'I WANNA CHAOS!' までジャンプする
I WANNA CHAOS! ポインタの指す値が0で無いなら 対応する 'CHAOS☆CHAOS!' までジャンプする
Let's\(・ω・)/にゃー ポインタの指す値を出力する
cosmic! 入力から1バイト読み込こむ

元のBrainf**kの命令(>+<-[].,)を置き換えているだけのネタ言語なのだが
これでもチューリング完全みたいです。


実行には同じ作者さんが公開している「r-fxxk」が必要なので予めダウンロードしてRUBYPATHを設定。
付属しているサンプルを以下で実行できる。

./nyaruko haiyoru_konton.nyaruko

Hello World!」が表示されればOK!

さっそく足し算プログラムを作成してみました。
一桁の数値を2つ入力し加算して表示するプログラムです。
ただし表示も一桁しかないので10以上は表示できません。

r-fxxkは1バイト読み込み命令が実装されてないので以下を追加。

r-fxxk/lib/r-fxxk.rb

69  when :get
70    cell[ptr] = STDIN.getc.bytes.to_a[0] #これを追加@Ruby1.9.2
      cell[ptr] = STDIN.getc               #Ruby1.8系だとこっち


adder.nyaruko

(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃーcosmic!(」・ω・)」うー(/・ω・)/にゃーcosmic!(」・ω・)」うー!!(/・ω・)/にゃー!!
Let's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーLet's\(・ω・)/にゃー(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー(/・ω・)/にゃー
CHAOS☆CHAOS!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!
(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー!!(/・ω・)/にゃー!!
(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー(/・ω・)/にゃーCHAOS☆CHAOS!(」・ω・)」うー!!(/・ω・)/にゃー!!(」・ω・)」うー!(/・ω・)/にゃー!(」・ω・)」うー(/・ω・)/にゃー(」・ω・)」うー!!!(/・ω・)/にゃー!!!I WANNA CHAOS!
(」・ω・)」うー!!(/・ω・)/にゃー!!Let's\(・ω・)/にゃー

実行

./nyaruko adder.nyaruko
12 <-数字2つ入力してEnter
1+2=3

ZedboardにDACを接続してみた-TLC7528C編-

AM変調した信号を出力するためにDACをいくつか買いましたのでZedboardに接続して信号を出力してみます。

まずは手持ちにあるTIのTLC7528C(10Msps)を使います。

今はまだFMCコネクタを使えないので使えるのはPmodしかありませんがPmodは8pinしかありません。
それに対してDACのブロック図は以下になっています。

f:id:ginnyu-tei:20121217005746j:plain


データは8bitなのでピッタリに見えますがそうすると制御線が繋げません。
Pmodを2つ使えば16bit分確保できますがPmod間で信号がずれないか心配なのでなるだけ8ピンに抑えます。

その為にデータを7bitデータ+WEの構成にします。
制御線は他にCSとDAC選択線(TLC7528CはA/B 2chのDAC搭載)がありますが固定にします。
(仕様書を見る限りWEも固定で大丈夫そうですが、オシロでデータを見やすくする為に出力)

ZedboardからDDSの出力をさせ、オシロスコープで観測した結果が以下になります。
f:id:ginnyu-tei:20130513214335j:plain

正弦波っぽく見えないのはOUTAをオシロに直結したので
ローパスフィルターを入れてないのが原因だと思います。

ノイズが多いのはブレットボードで空中配線をしているからでしょうか?

root権限のないlinuxへ色々インストールしてみた

root権限がないlinux上で色々ツールを使いたかったのでやってみた。

今回のターゲットは以下の制限がついています。

  • root権限がない
    • yum使えない
    • アクセスできる範囲が限られている
  • インターネットにつながらない
    • wgetが使えない
    • sambaとFTPは動いている。

こういう場合の基本方針は以下の通り

・必要なライブラリはすべて別PCでダウンロード -> Samba or FTPで転送
・configure -> make -> make installの流れ
・--prefixでインストールパス設定
・ライブラリパスはsetやLD_LIBRARY_PATHで指定

インストールしたのは↓
Perl+module
・tmux
Python
Vim
・tree
・OpenBox

折角なので一気にインストールするスクリプトを書いてみた。
set INSTHOME でインストール先の設定。
set ??_INST=でインストールする/しないを選択

#! /bin/csh -f
set lNSTHOME = <ツールインストール先>
set TOOLHOME = ./
setenv PKG_CONFlG_PATH $lNST_HOME/lib/pkgconfig

set PERL_INST=0

set PERL_MOD_INST=0
set PERL_MOD_LIST
set PERL_MOD_LIST = ($PERL_MOD_LIST Verilog-Perl-3.313.tar.gz)
set PERL_MOD_LlST = ($PERL_MOD_LIST Jcode2.0.7.tar.gz)
set PERL_MOD_LIST = ($PERL_MOD_LIST XML-Parser-2.36.tar.gz)
set PERL_MOD_LlST = ($PERL_MOD_LlST Tk-804.030.tar.gz)
set PERL_MOD_LlST = ($PERL_MOD_LIST Spreadsheet-ParseExcel-0.59.tar.gz)
set PERL_MOD_LlST = ($PERL_MOD_LlST Crypt-RC4-2.02.tar.gz Digest-Perl-MD5-1.8.tar.gz OLE-Storage_Lite-0.19.tar.gz IO-stringy.tar.gz
set PERL_MOD_LIST = ($PERL_MOD_LlST Spreadsheet-WriteExcel-2.37.tar.gz) #<-Warning:prerequisiteParse::RecDescent 0 not fount
set TMUX_lNST=0
set PYTHON_INST=0
set VIM_INST=1
set TREE_INST=0
set OPENBOX_INST=0

#perl 5.14.2 ##

if ($PERL_INST == "1") then
	cd $TOOL_HOME/perl/
	tar zxvf perl-5.14.2.tar.gz
	cd perl-5.14.2
	./Configure -des -Dprefix=$INST_HOME

	#make test
	make -j 4
	make install
	
	if(-e $INST_HOME/bin/perl) then
		rm -rf perl-5.14.2
	endif

	## perl module ##
	if($PERL_MOD_INST ==  "1") then
		foreach hoge ( $PERL_MOD_LlST )
			tar zxvf $hoge
			cd `echo $hoge | sed 's/.tar.gz//g'`
			$INST_HOME/bin/perl Makefile.PL
			make 
			#make test
			make install
			cd ../
			rm -rf `echo $hoge | sed 's/.tar.gz//g'`
		end
	endif
	cd ../
endif

## tmux ##
if ($TMUX_INST == "1")  then
	cd tmux
	tar zxvf libevent-2.0.16-stable.tar.gz
	cd libvevnt-2.0.16-stable.tar.gz
	make -j 4
	make install
	cd ../
	rm -rf libevent-2.0.16-stable
	
	tar zxvf tmux-1.5.tar.gz
	cd tmux-1.5
	./configure --prefix=$lNST_HOME -CFLAGS="-l$INST_HOME/include" LDFLAGS="-L$lNST-HOME/lib"
	make -j 4
	make install
	rm -rf tmux-1.5
	cd ../
endif

## Python ##
if ($PYTHON_INST == "1") then
	cd Python
	tar zxvf Python-2.7.2.tar.gz
	cd Python-2.7.2
	./configure --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$INST_HOME/lib"
	make -j 4
	make install
	cd ../
	rm -rf Python-2.7.2
	cd ../
endif
## Vim ##
	if ($VIM_INST == "1") then
	tar jxvf vim-7.3.tar.gz
	cd vim73
	cat ../patches_vim73/7.3.* | patch -p0
	./configure --enable-multibyte --enable-fontset --wlth-features=big--enable-perlinterp --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$lNST_HOME/lib"
	make -j 4
	env LANG="ja_JP.UTF-8" makeinstall #LANG設定はsed-4.1.5のバグ(?)回避
	cd ../
	rm -rf vim73
	cd ../
endif

## tree ##
if ($TREE_INST == "1") then
	tar zxvf tree-1.6.0
	make -j 4
	tar zxvf tree-1.6.0.tar
	cd tree-1.6.0
	make -j 4
	cp tree $INST_HOME/bin
	cd ../
	rm -rf tree-1.6.0
endif

## openbox ##
if ($OPENBOX_INST == "1") then
	cd openbox
	tar zxvf imlib2-1.4.4.tar.gz
	cd  imlib2-1.4.4
	./configure --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$INST_HOME/lib"
	make -j 4
	make install
	cd ../
	rm imlib2-1.4.4
	
	tar zxvf hsetroot-1.0.2.tar.gz
	cd hsetroot-1.0.2
	./configure --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$INST_HOME/lib"
	make -j 4
	make install
	cd ../
	rm hsetroot
	
	tar zxvf openbox-3.4.0.tar.gz
	cd openbox-3.4.0
	./configure --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$INST_HOME/lib"
	make -j 4
	make install
	cd ../
	rm -rf openbox-3.4.0
	tar zxvf obconf-2.0.0.tar.gz
	cd obconf-2.0.0
	./configure --prefix=$INST_HOME CFLAGS="-l$lNST_HOME/include" LDFLAGS="-L$INST_HOME/lib"
	make -j 4
	make install
	cd ../
	rm -rf obconf-2.0.0.tar.gz

	#pypanel
	cd PyPanel
	tar zxvf python-xlib-0.15rc1.tar.gz
	cd python-xlib-0.15rc1
	$INST_HOME/bin./python ./setup.py install
	cd ../
	rm -rf python-xlib-0.15rc1
	
	tar zxvf PyPanel-2.4.tar.gz
	cd PyPanel-2.4
	patch < ./setup_path_change.py.patch # <-setup.pypyのパス(configsとimlib2)を書き換え
	$INST_HOME/bin/python ./setup.py install
	cd ../
	rm -rf PyPanel-2.4
	
	cd ../

endif

Vivado HLSでOpenCVを試してみた

仕事が忙しく更新が止まってます。4月に入れば更新速度上げれそうです。

さて、先週ツイートしましたがFPGA2013というイベントの資料を見つけました。


で、その資料の中にVivadoHLSのOpenCVがちょっとだけ載っていましたので試してみました。

結果からいうと合成はできた(っぽい)けどシミュレーションがエラーで動かない状態です。

以下コード

  • TB.cpp
#include "TOP.h"
#include "opencv2/opencv.hpp" //OpenCV2.4だと必要

//using namespace cv;

int main(void) {
	IplImage* src=cvLoadImage("test_1080p.bmp");
	IplImage* dst=cvCreateImage(cvGetSize(src),
			src->depth, src->nChannels);
	AXI_STREAM src_axi, dst_axi;
	IplImage2AXIvideo(src, src_axi);
	top(src_axi, dst_axi, src->height, src->width);
	AXIvideo2IplImage(dst_axi, dst);
	cvSaveImage("result_1080p.bmp", dst);
	cvReleaseImage(&src);
	cvReleaseImage(&dst);

	return(1);
}
  • top.h
#ifndef __TOP__H__
#define __TOP__H__

#include "hls_video.h" // header file of HLS video library
#include "hls_opencv.h" // header file of OpenCV I/O
// typedef video library core structures
typedef hls::AXI_Base<32> AXI_PIXEL;
typedef hls::stream<AXI_PIXEL> AXI_STREAM;
//typedef hls::Scalar<3, uchar> RGB_PIXEL; //ucharが見つからない
typedef hls::Scalar<3, unsigned char> RGB_PIXEL;
typedef hls::Mat<1080,1920,HLS_8UC3> RGB_IMAGE;

void top(AXI_STREAM& src_axi, AXI_STREAM& dst_axi, int rows, int cols);

#endif //__TOP__H__
  • top.cpp
#include "TOP.h"
//#include "ap_interfaces.h" 


void top(AXI_STREAM& src_axi, AXI_STREAM& dst_axi, int rows, int cols){
	//Create AXI streaming interfaces for the core
	#pragma HLS RESOURCE core=AXIS variable=src_axi metadata="-bus_bundle INPUT_STREAM"
	#pragma HLS RESOURCE core=AXIS variable=dst_axi metadata="-bus_bundle OUTPUT_STREAM"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=rows metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cols metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"
	//RGB_IMAGE img[6];

	RGB_IMAGE img[5]; //hls::Sobelをはずしたので要素を減らす

	RGB_PIXEL pix(100,100,100);
	#pragma HLS dataflow
	hls::AXIvideo2Mat(src_axi, img[0]);
	//hls::Sobel(img[0], img[1], 1, 0); //hls::Sobelは未実装だった
	hls::SubS(img[0], pix, img[1]);
	hls::Scale(img[1], img[2], 2, 0);
	hls::Erode(img[2], img[3]);
	hls::Dilate(img[3], img[4]);
	hls::Mat2AXIvideo(img[4], dst_axi);
}

OpenCVのライブラリはVivadoHLS内になかったので別途インストールしました(OpenCV2.4)
Windowsでのライブラリパスの設定方法が分からなかったので以下ベージを参照しました。

http://stackoverflow.com/questions/10860352/getting-started-with-opencv-2-4-and-mingw-on-windows-7


この記述でシミュレーションを実行すると

 e:/xilinx/vivado_hls/2012.4/msys/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: cannot find -lopencv_core240
 e:/xilinx/vivado_hls/2012.4/msys/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: cannot find -lopencv_highgui240

ライブラリを読めてないようです。(x86のライブラリで大丈夫なはず・・・)
Windowsだとどこに問題があるか調べにくいのでLinux環境で試せたらやってみたいです。