FPGAのコーディングで困惑する方が多い点として、ソースコードすべてが「同時に動く」ということがあります。ソフトウェアのプログラミング言語を最初に学んだ方からすると、FPGAのコーディングは難しく感じるそうです。
今回は、FPGAのソースコードの読み方、書き方の基本となる考え方について説明します。この考え方があれば、特に初心者の方はかなりFPGAのコードの読み書きが楽になると思います。
目次
まずは、ソフトウェア開発におけるプログラミング言語から見ていきます。
C言語で次のようなソースコードであれば、ざっくりと図1のように動作します。言うまでもなく、ソースコードの上から順番に実行されます。すなわち、ソフトウェアのプログラミングのソースコードは時系列に書かれます。したがって、書く側の人間の思考も時系列になります。「まずはこれを処理して、次にあれを処理して… 」というかんじです。
1 2 3 4 5 6 7 8 9 | int sum3(int a, int b, int c) { int x, y; x = a + b; y = x + c; return y; } |
FPGAを記述する2大言語の1つである、Verilog HDLで例を示します(ちなみにもう一つはVHDL)。
次のVerilog HDLのコードは、図2の回路になります。”|”は論理和(ORゲート)です。
1 2 3 4 5 6 7 8 9 10 11 12 13 | module or3( input a, input b, input c, output y ); wire x; assign x = a | b; assign y = x | c; endmodule |
このとき、
これらは、図2のようなORゲートを置いているイメージでコーディングします。10行目と11行目を逆の順で書いた次のコードも、図2の回路となり、全く同じ動作をします。ORゲートを置くことは変わらず、2つのORゲートを信号xで接続することも変わらないからです。
1 2 3 4 5 6 7 8 9 10 11 12 13 | module or3( input a, input b, input c, output y ); wire x; assign y = x | c; assign x = a | b; endmodule |
次のVerilog HDLのソースコードは図3の回路になります。
こちらも前の例と同様に、always文で組合せ回路とフリップフロップを置くイメージでコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | module or4reg( input clk, input a, input b, input c, input d, output y ); reg p; reg q; always @ (posedge clk) begin p <= a | b; end always @ (posedge clk) begin q <= c | d; end assign y = p | q; endmodule |
以上のように、FPGAのプログラミングでは、回路の部品を置いていくイメージで書いていきます。つまり、ソースコードは空間です。空間に置いた部品はハードウェアですので、すべて同時に動くのは当然といえば当然なわけです。
回路の部品はソースコード内のどこに書いても、同じ動作をします。例えば、次のコードも図3の回路になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | module or4reg( input clk, input a, input b, input c, input d, output y ); reg p; reg q; always @ (posedge clk) begin q <= c | d; end assign y = p | q; always @ (posedge clk) begin p <= a | b; end endmodule |
ソースコード内で書く順番を決めるとすれば、人間が読み書きしますので、信号の流れの順で書くのがよいです。読みやすくなり、メンテナンスしやすいです。図2, 図3では信号が左から右に流れますので、ソースコードでは左側の部品をなるべく上に書きます。
この記事内ですでに使っていましたが、上記コードのwire x, reg p, reg qなどを信号といいます。変数とはいいません。
上記で解説したように、FPGAのプログラミングは部品を置いて接続していく作業です。接続するための信号線の名前がxとかqとかpである、ということになります。