FPGA – DECODE https://decode.red/blog data decode, decoder or decoded ... design of code Mon, 15 Dec 2025 06:15:00 +0000 ja hourly 1 https://wordpress.org/?v=4.7.29 FPGA Verilog / Altera ModelSim ../../../20161229641/ Thu, 29 Dec 2016 02:01:32 +0000 ../../../?p=641 field-programmable gate array : ユーザが構成を設定できる集積回路。

以前も下記でとりあげました。
「FPGA & GPU/OpenCL」
../../../20150913427/

このときはソフトウェアエンジニア目線でFPGAというものを見ていましたが、最近電子工作を始めるようになって、FPGAについてまた違った魅力を感じるようになりました。
そこで最近Altera MAX10ボードを購入したことから、AlteraのツールのModelSimを試してみました。
ここではFPGAプログラミングの初歩であるビットカウンタをツールのチュートリアルをもとにシミュレートしました。

環境 : ModelSim ALTERA STARTER EDITION 10.4b / Windows 10
tcounter.v

`timescale 1ns / 1ns
module test_counter;

reg clk, reset;
wire [7:0] count;

counter dut (count, clk, reset);

initial // Clock generator
  begin
    clk = 0;
    forever #10 clk = !clk;
  end
  
initial	// Test stimulus
  begin
    reset = 0;
    #5 reset = 1;
    #4 reset = 0;
    #150 reset = 1;
    #4 reset = 0;
  end
  
initial
    $monitor($stime,, reset,, clk,,, count); 
    
endmodule

counter.v

`timescale 1ns / 1ns
module counter (count, clk, reset);
output [7:0] count;
input clk, reset;

reg [7:0] count;

always @ (posedge clk or posedge reset)
  if (reset)
     count = 8'h00;
  else
     count <= count + 8'h01;

endmodule

[File]->[Change Directory]でソースがあるフォルダを選択します。
[Compile]->[Compile]を選択すると以下の画面がでてくるのでソースを選択します。
sim_01

ソースと同じ階層に以下のようなcompileというファイルがあるので、自動的にworkフォルダが作成されるみたいです。

#!/bin/csh
if (! -e work) then
	vlib work
endif
vlog counter.v tcounter.v

[Simulation]->[Start Simulation]でtest_counterを選択します。
sim_02

入力フォームRun Lengthを500nsにして、右のRunボタンを押すと、シミュレーション結果が表示されます。
sim_03

テストではリセットでインクリメントされてきたカウントがリセットされて、また再開していることを確認できます。
sim_04

FPGAではCPUも構成できます。つまりCPUを構成するのもデータ、そのCPUで走るプログラムもデータです。今回のテストのような単純なビットカウンタのようなものと区別しません。(Verilog-HDLでハードウェアを記述してデータを操作する)
最近いろいろと話題となっているFPGAが利用用途が広いのも納得できます。
またコンピュータの基本、デジタルであるということが、これだけいろんな技術が発達しても何も変わっていないことを再認識させられます。

今の目標としてはリアルタイムの画像データ処理で使えるようにしたいです。

またハードウェアに関して新しいブログもはじめました!

em7s

]]>
FPGA & GPU/OpenCL ../../../20150913427/ Sun, 13 Sep 2015 04:22:30 +0000 ../../../?p=427 インテルによるアルテラ買収のニュースは、これからのソフトウェア開発手法について何らかの変化があるのではないか、と思わせてくれます。
(http://systems.blue/blog/archives/25)

インテル、プログラマブルなLSI「FPGA」大手のアルテラ買収を発表。XeonにFPGAを組み込む計画も表明
http://www.publickey1.jp/blog/15/lsifpgaxeonfpga.html

メインCPU以外のプロセッサによる処理は、ゲーム機開発などでは当たり前ですが、私がそのパワーを体感したのはPlayStation2の開発のときでした。立体音響のマトリックス演算でしたが、メインCPUの何十倍の処理をやってのけました。
最近、前の記事でとりあげた言語処理だったり、機械学習などでも、GPUを活用する事例をよく見かけます。やはりこれからは、並列処理の考え方でプログラムを書く力が必要になるのでは、ということで、実際にプログラムを動かして頭をならしておこうと思い立ちました。

まずFPGAですが、Icarus Verilog というツールを使って、Ubuntu14.04 上で実行しました。ハードウェア記述言語ですが、シミュレーションしてくれます。

module test1;
	reg [31:0] i = 0, j = 0;
	reg clk = 1'b0;
	reg done = 1'b0;
	always @(posedge clk) begin
		i = i + 1;
		i = i + 1;
		j <= j + 1;
		j <= j + 1;
		if ( i >= 100 ) begin
			done = 1;
		end
	end
	initial begin
		clk = 0;
		while(!done) begin
			clk = 0; #10;
			clk = 1; #10;
		end
		$write("%d %d\n", i, j);
	end
endmodule

apt-get install iverilog
iverilog -o test1 test1.v
vvp test1

実行すると、100 と 50 が表示されます。
alwaysブロックがクロックのタイミングで呼び出されるのですが、ここにステータスを分けたりして、並列処理を書くようです。(データ並列・パイプライン並列) ここに複数の処理を書くために、通常のプログラムと違うしくみがあります。i はブロッキング代入、j はノンブロッキング代入といい、j は、alwaysブロックが終わった時点で確定されます。そのため、jはiの半分の値となっています。

参考 : インターフェイスZERO No.4

次に、OpenCLですが、OpenGL、OpenCVと似ていて間違えそうになりますが、違います。
同じようなものに、CUDAというのがありますが、NVIDIAのGPUでないと動作しないので、汎用性の高い方を選びました。またMacのXcodeが対応していることから、特にライブラリ、プラグイン等をインストールしなくてもいいので便利です。

opencl_xcode

このコードは下記OpenCL Sample Codesのものを実行しました。
https://iws44.iiita.ac.in/wiki/opencl/doku.php?id=mul24

Xcodeで動かすための修正点は、ヘッダ(OpenCL/opencl.h)とCLコードのファイルパス(絶対パス)です。
またGPUが対応していなくても、CL_DEVICE_TYPE_DEFAULTでデバイスを取得すれば実行できるみたいです。

// Step 02: Get information about the device
    err = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices );
    //err = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id, &ret_num_devices );

kernel.clで受け取っているget_global_idは、worksizeで設定されている次元のそれぞれの数分、ループされます。このサンプルだと、yは1に固定されています。

// Step 11: Execute OpenCL kernel in data parallel
    size_t worksize[] = { MAT_SIZE, 1, 1 };
    clEnqueueNDRangeKernel( command_queue, kernel, 1, NULL, worksize, 0, 0, 0, 0 );
    err_check( err, "clEnqueueNDRangeKernel" );

このclEnqueueNDRangeKernelがkernel.clのプログラムを同時実行させますが、順番は保証されないようです。

GPGPU(General-purpose computing on graphics processing units)、
FPGA(field-programmable gate array)のどちらが、主流になっていくかわかりませんが、このようなプログラミングの考え方はもっとトレーニングしたいと思っています。

]]>