2017年7月18日火曜日

Vivado CASE文の不具合 調査中

どうやら 
”メモリを推定する記述の場合に不具合が出る”
ようです。

■サンプル1 2bitGCC
reg [1:0] gcc
    always @ (posedge CLK or posedge RST) begin
        if (RST) gcc <= 0;
        else
          case (gcc)
            0 : gcc <= 1;
            1 : gcc <= 3;
            3 : gcc <= 2;
            2 : gcc <= 0;
            default : gcc <= 0;
          endcase

2bitのカウンタ(GrayCode)をcase文で記述。結果RTL記述より2個多い、4bit分のレジスタが合成された
これに対しては、前回に書いたように、
Gray2Bin→+1→Bin2Gray→Reg
の回路を記述すれば最小構成で合成される。

■サンプル2 4input RoundRobinArbiter

    reg [3:0] timeout_counter;
    reg [2:0] sequence;
    wire timeout;

always @ (posedge CLK or posedge RST) begin
      if (RST) sequence <= 0;
      else begin
        case (sequence)
          0 : if (REQUEST1) sequence <= 1;
              else if(REQUEST2) sequence <= 2;
              else if(REQUEST3) sequence <= 3;
              else if(REQUEST4) sequence <= 4;
          1 : if (!REQUEST1 || timeout) begin
                if(REQUEST2) sequence <= 2;
                else if(REQUEST3) sequence <= 3;
                else if(REQUEST4) sequence <= 4;
                else if (REQUEST1) sequence <= 1;
                else sequence <= 0;
              end
          2 : if (!REQUEST2 || timeout) begin
                  if(REQUEST3) sequence <= 3;
                  else if(REQUEST4) sequence <= 4;
                  else if(REQUEST1) sequence <= 1;
                  else if (REQUEST2) sequence <= 2;
                  else sequence <= 0;
                end
          3 : if (!REQUEST3 || timeout) begin
                  中略
                end
          4 : if (!REQUEST4 || timeout) begin
                  中略
                end                    
          default : sequence <= 0;
        endcase
      end
    end
 
    assign GRANT1 = (sequence == 1);
中略
 
    //timeout counter
    always @ (posedge CLK or posedge RST) begin
      if (RST) timeout_counter <= 0;
      else begin
        if (sequence == 0) timeout_counter <= 0;
        else timeout_counter <= timeout_counter+1'b1;
      end
    end
    assign timeout = (timeout_counter == 4'hf);

4bitのタイムアウトカウンタと3bitシーケンス制御用レジを記述。結果はRTL記述と同じ7個のレジスタが合成された。
シーケンサの記述に関しては問題なさそうです。

■おまけ ラウンドロビンの配置結果
レジスタ7個に対しLUTが22個なので、このようにスカスカ。記述を工夫すれば詰められそうですが・・ 

2017年7月16日日曜日

vivado におけるグレイコードカウンタの書き方

Vivadoにおけるというか、XilinxのFPGA向けというか、
6LUTを持つFPGA向きの記述というか、なんかそんな感じです。

前回、case文でグレイコードカウンタを記述すると意図しないレジスタを生成することが分かったので、他の記述をした場合にどのような回路を合成するか調べてみた。

1:加法標準形による記述
always @ (posedge CLK or posedge RST) begin
        if (RST) gcc <= 0;
        else begin
            gcc[5] <= (gcc[5:0]==6'b010000)||(gcc[5:0]==6'b110000)|| ...中略
    ・・・中略
       end
end

前回と同じ加法標準形による記述では、正しく意図した回路を生成する。

2:いちどバイナリになおして加算してグレイにして(略
Gray2Binaryとインクリメント演算で2度のリップルキャリーが出るため、避けるべきと思っていた記述だが(少なくともsynopsysでは避けていた)、vivadoではリップルキャリーの出る部分は全て6入力LUTに吸収され、加法標準形による記述と同様の回路が生成された

module GRAYCODECOUNT(
    input CLK, RST,
    output [5:0] GOUT
);

reg [5:0] gcc;
wire [5:0] gray2bin;
wire [5:0] inc;
wire [5:0] bin2gray;
    
assign gray2bin[5:0] = gcc[5:0] ^ {1'b0, gray2bin[5:1]};
assign inc  = gray2bin[5:0] + 1'b1;
assign bin2gray = inc[5:0] ^ {1'b0, inc[5:1]};
always @ (posedge CLK or posedge RST) begin
  if (RST) gcc <= 0;
  else gcc <= bin2gray;
end
    
assign GOUT = gcc;
endmodule

結論 Vivadoの合成では、いらんこと考えずにビヘイビアレベルで記述したほうが良かったりしますよ

vivado case文の不具合?

vivado2017.1でcase文を使ったら、意図しない回路を生成してくれやがったのでメモ。

module graycounter_3bit(
  input CLK, RST,
  output [2:0] GOUT
);
reg [2:0] gc3;
always @ (posedge CLK or posedge RST) begin
  if (RST) gc3 <= 0;
  else
    case (gc3)
      3'b000 : gc3[2:0] <= 3'b001;
      3'b001 : gc3[2:0] <= 3'b011;
      3'b010 : gc3[2:0] <= 3'b110;
      3'b011 : gc3[2:0] <= 3'b010;
      3'b100 : gc3[2:0] <= 3'b000;
      3'b101 : gc3[2:0] <= 3'b100;
      3'b110 : gc3[2:0] <= 3'b111;
      3'b111 : gc3[2:0] <= 3'b101;
      default : gc3[2:0] <= 3'bxxx;
    endcase
  end
  assign GOUT[2:0] = gc3[2:0];
endmocule

上のような3ビットのグレイコードカウンタを記述したところ、
下のような8bitのレジスタ+LUTの回路を生成しやがりました。

出力はちゃんとグレイコードしてますが、せっかくグレイコードカウンタを記述してるのに回路面積を増やしてくれやがるのはダメですね。ちゃんとレジ止めしてるのに出力段にLUTを生成してくれやがるので、ゲートシムするとヒゲが出ます。一番ダメなのは、3bitのレジを作ったつもりが8bitになってるあたり。

というわけでマニュアルオプティマイズをした3bitグレイコードカウンタを作成し、コンパイルしてみました。

module graycounter_3bit(
  input CLK, RST,
  output [2:0] GOUT
);
reg [2:0] gc3;
always @ (posedge CLK or posedge RST) begin
  if (RST) gc3 <= 0;
  else begin
            gc3[0] <= (!gc3[2] && !gc3[1]) || (gc3[2] && gc3[1]);
            gc3[1] <= (!gc3[2] && gc3[0]) || (gc3[1] && !gc3[0]);
            gc3[2] <= (gc3[1] && !gc3[0]) || (gc3[2] && gc3[0]);
    end
  end
endmodule


こちらで合成すれば、ちゃんと意図した回路を生成してくれます。

case文を使った箇所を一度見直す必要がありそうです orz

追記 4bitグレイコードカウンタ
加法標準形を書き出しただけですが、オプティマイズされた回路が出力されるようです。
ZYNQのLUTが6bitなので、6bitまでなら、このやり方で最適な回路が生成されるかと思われます。

 reg [3:0] gc4;
 always @ (posedge CLK or posedge nRST) begin
    if (nRST) gc4 <= 0;
    else begin
      gc4[0] <= (gc4 == 4'b0000) || (gc4 == 4'b0001) || (gc4 == 4'b0110) || (gc4 == 4'b0111) || (gc4 == 4'b1100) || (gc4 == 4'b1101) || (gc4 == 4'b1010) || (gc4 == 4'b1011);
      gc4[1] <= (gc4 == 4'b0001) || (gc4 == 4'b0011) || (gc4 == 4'b0010) || (gc4 == 4'b0110) || (gc4 == 4'b1101) || (gc4 == 4'b1111) || (gc4 == 4'b1110) || (gc4 == 4'b1010);
      gc4[2] <= (gc4 == 4'b0010) || (gc4 == 4'b0110) || (gc4 == 4'b0111) || (gc4 == 4'b0101) || (gc4 == 4'b0100) || (gc4 == 4'b1100) || (gc4 == 4'b1101) || (gc4 == 4'b1111);
      gc4[3] <= (gc4 == 4'b0100) || (gc4 == 4'b1100) || (gc4 == 4'b1101) || (gc4 == 4'b1111) || (gc4 == 4'b1110) || (gc4 == 4'b1010) || (gc4 == 4'b1011) || (gc4 == 4'b1001);
   end
  end
assign GOUT = gc4;

2017年6月29日木曜日

VivadoでIPを作るのが…

1:一度、素プロジェクトでRTL作って
2:ビヘイビアSIMが通ったら、IPパッケージャー起動してRTLをコピー、AXI仕様にして
3:ブロックデザインで組み込んでタイミング検証して
4:SlackがMetしなければ1へ戻り
を繰り返してる。 すげー面倒。 
もっと楽にやる方法はないものか。

XilinxのチュートリアルにIPを作るのがあるけど、
もともと完成してるRTLをそのままAXI仕様にするだけの簡単なお仕事なので、
タイミングがシビアな回路の組み立てチュートリアルみたいなのが欲しい。

などとぼやいてみたり。

2017年6月25日日曜日

SimpleScreenCapture

シンプルなスクリーンショットツール。

CAPTUREボタンを押せば、テキストボックスに指定した場所にCAPフォルダを作成し、連番のpngファイルで保存します。 
MMD、Blender作業中の様子をBlogにアップしたいなどと思っている人向け。 
キャプチャしたあとに、GIMPやPhotoshop,ペイントなどで加工してください。

ダウンロードはこちら → https://bowlroll.net/file/140491

EXEファイルですので、SHA1、MD5などのチェックサムを確かめた上でご使用ください。
外部ネットワークにアクセスするようなコードは含まれていませんので、もしそのような不審な動作をするようでしたら、直ちに使用を停止し、お手数ですがTwitter@PiT_shanまでご報告頂けると助かります。

なお、Twitterなどでのインスタント共有には向きませんので、Gyazoなどをお使い下さい。

まぁ、あれです。
Vivado2017の日本語チュートリアルを作成しようとして、SnippingToolで切り取ってたのですが、途中で面倒になって脱線した結果。


2017年6月10日土曜日

Raspberrypi3のWiFiを無効にしたり固定IPを割り当てたり

固定IPについては、
 -ルータ側の固定IPさえ設定しておけば、自動的に固定される
 -RPi側はデフォルトのままでOK

念のためRPi側の設定手順
# /etc に移動
cd /etc

###バックアップする
sudo cp dhcpcd.conf dhcpcd.conf.bak

# dhcpcd.confを修正
sudo vi dhcpcd.conf
###全部消して次の2行を足す
interface eth0
static ip_address=192.168.xxx.yyy/24


WiFiの電源をコントロールするには、

#WiFi電源OFF
sudo iwconfig wlan0 txpower off

#WiFi電源ON
sudo iwconfig wlan0 txpower auto

OFFしたあとにifconfigすると、wlan0の項目が消えます。

これで数十mA節約できる模様。

参照: https://raspberrypi.stackexchange.com/questions/43720/disable-wifi-wlan0-on-pi-3

2016年10月11日火曜日

ZYBOのPLだけを使う場合のクロックソース

ZYNQのクロックですこし罠にはまったのでメモ。

ZYNQにはPLで使えるクロックソースが
1:ZynqPSから供給されるFCLK_CLK[3:0]
2:EthernetPHYから供給されるリファレンスクロック(125MHz)が L16ピンに接続されている
このうちFCLK_CLKは、PS部分が動作していないと起動しないらしい。
そのためPL(Logic部)単体で使う場合は、L16を使うことになる。

ARMコア(PS)の起動プログラムをちゃんと書けばFCLKも使えるんだろうけど、めんどくさいので暫くはL16を使ってロジック開発しようと思う。

なお、このことはZYBOマニュアルの
12 ClockSources
に記載されていました。



先週、ZYBOとかいうARMコアとFPGAがワンチップになった実験ボードを購入しました。
なお、FPGAとは呼ばずAPSoC(AllProgrammableSoC)と呼ぶらしい

最近のFPGAはコンフィグROMじゃなくSDカードを使うんですなー。賢い

あとVivadoおもろい

追記 Vivadoの推奨OSがWindows10Proだったのですが、今のところVivado、VivadoHLSともにWindows10Homeでも動作しています。