FPGA入門 備忘録④ 〜順序回路編〜
備忘録③の続きになる。
RSフリップフロップ
上図はORゲートを用いた状態記憶回路である。ORゲートの出力Qが一方の入力に帰還しているため入力Sが一度1になると、出力Qはその後、入力Sの状態にかかわらず1を保持し続ける。
上図は、最初の回路にリセット入力Rを追加したもので、これにより出力Qを0に戻すことが可能になる。 以下にRSフリップフロップの真理値表を示す。入力SとRが共に0の時は共に0となる直前の出力Qが保持される。ただし、直前の入力が共に0の時は、いずれの値が保持されるかは分からない。 Rが0でSが1の時、Q=1、Rが1でSが0の時はQ=0となる。R=1、S=1の時、Q=1となるが、この状態からR=0、S=0となった場合に、Q=1の保持が確実でないのは各ゲートの遅延などでR=1、S=0となってからR=0、S=0となる可能性があるためだ。そのため、R=1、S=1は一般に使わない。
入力 | 出力 | |
---|---|---|
R | S | Q |
0 | 0 | 前の状態 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 1 | 1(使用禁止) |
上に簡略化の流れを示す。まずひとつ目の図はORゲートをNORゲートに変更して、ふたつ目の図のように書ける。次に、ふたつ目の図のANDゲートはNOTゲートと組み合わせて、3つめの図のようにNORゲートに置き換え可能だ。ここで、各NORゲートの出力をそれぞれQ、Q_とすると、4つ目の図のようになる。
4つ目の図の真理値表を書くと、
入力 | 出力 | ||
---|---|---|---|
R | S | Q | Q'|Q_ |
0 | 0 | 前の状態 | 前の状態|前の状態 |
0 | 1 | 1 | 1|0 |
1 | 0 | 0 | 0|1 |
1 | 1 | 1 | 0|0 |
ここで、前述のようにRとSが共に1の時に使わないのであれば、Q=Q'として更に、5つ目の図のように簡略化できる。
入力 | 出力 | ||
---|---|---|---|
R | S | Q | Q_ |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 0(使用禁止) | 0(使用禁止) |
最後に、5つ目の図は6つ目のよく見る図のように簡略化できる。 簡略化しNORゲートのみを使って表すことで、回路規模が小さくできる。XilinxのFPGAではプリミティブとして、後述のDフリップフロップと同期セット・リセット入力付きDフリップフロップなどが用意されている。 ただ、これらのプリミティブを用いずに基本ゲート(Look Up Table)のみを用いて、フリップフロップを構成することができる。
module RSFF_VERILOG(SW0, SW1, LED0, LED1); input SW0; input SW1; output LED0; output LED1; assign LED0 = ~(SW0 | LED1); assign LED1 = ~(SW1 | LED0); endmodule
Dフリップフロップ
RSフリップフロップはSにセットした値、もしくはRでリセットした値を時間経過に関係なく保持することができる1bitのメモリだ。しかし、その値を保持するためにはS=0、R=0という状態を保持する必要がある。これではまだ使い勝手が悪い。つまり実際の回路ではある瞬間のみに値の書き込みを行い、それ以降はSおよびRの状態と無関係に値を保持する動作を求められる。そのような動作を実現するために書き込む値を入力する端子と書き込み制御を行う端子を分離したフリップフロップの一つがDフリップフロップだ。このDフリップフロップと後で説明するクロックイネーブル入力付きDフリップフロップ、及び基本ゲートがあればほとんどの完全同期式回路を記述できる。
以下にDフリップフロップの回路シンボルと真理値表を示す。
入力 | 出力 | ||
---|---|---|---|
D | CLK | Q | |
0 | ↑ | 0 | |
1 | ↑ | 1 | |
0 | - | 直前の値 | |
1 | - | 直前の値 |
DフリップフロップはDの入力状態をCLKから入力される信号の立ち上がりエッジで取り込み、Qに出力する。Qの出力は次のCLKの立ち上がりエッジが来るまで、変化しない。特に断りがなければ、立ち上がりエッジで取り込むポジティブエッジタイプを使う。立ち下がりで取り込むネガティブエッジタイプのシンボルを参考までに以下に示す。
RSフリップフロップはRとSを用いて、書き込むデータを表すとともに書き込むか、保持するかの動作の制御も行っていた。これに対し、Dフリップフロップではデータを入力するDと書き込み制御を行うCLKという風にデータ入力と制御入力を分離している。このデータと制御の分離は非常に重要で、大きな回路規模の設計を行うときには、データパスの設計なのか、制御パスの設計なのかを常に意識する必要がある。
module DFF_VERILOG(SW0, SW1, LED0); input SW0; input SW1; output LED0; reg LED0; always @(posedge SW1) begin LED0 <= SW0; end endmodule
always文のところで、DFFの制御を書いている。SW1の立ち上がりエッジで、SW0の値が取り込まれ、LED0に出力される。
セットアップ時間とホールド時間
DフリップフロップはCLKに入力される信号の立ち上がりエッジでデータを取り込む。したがって、データ入力はCLKの立ち上がりエッジ以前に確定している必要がある。このCLKの立ち上がりエッジからデータが確定していなければならない時間がセットアップ時間tsである。 また、内部のRS-FFが安定し、入力データがDフリップフロップに取り込まれるまでには時間を要する。したがって、入力データはCLKの立ち上がりエッジから特定の時間以上保持する必要があり、この時間がホールド時間thである。よって、ts+thの期間はデータ入力は0または1のいずれかに保持しなければならない。
トグルフリップフロップ
トグルフリップフロップの回路図を示す。Dフリップフロップの出力Qが自己のデータ自己DにNOTゲート経由で帰還されている。
Dフリップフロップの初期状態Q=0とすれば、Qは1となる。最初のクロックの立ち上がりで、Q=1が取り込まれ、直後にQ=1、Q=0となる。次のクロックの立ち上がりで、Q=0が取り込まれるので、直後にQ=0、Q=1となる。出力Qから出力される信号は、入力されるクロック周波数の半分の周波数となるため、この回路を2分周回路という。
上の回路は常にクロック信号の1/2の周波数の信号を生成するが、これを以下のように変更すると、制御信号T=1の間だけ1/2の周波数の信号を出力し、T=0のときは前の値を保持することができる。
この回路をシンボルで書くと以下のようになる。
module TFF_VERILOG(PSW0, LED0); input PSW0; output LED0; reg LED0; always @ (posed PSW0) begin LED0 <= ~LED0; end endmodule
クロックイネーブル
前述のDフリップフロップでは次のクロックの立ち上がりまでの期間、データの記憶が可能だが、もっと長い期間データを記憶しておくことが必要だ。そこで、次のクロックが来ても、データを更新しないような制御入力端子を追加したものが、クロックイネーブルだ。
クロックイネーブル付きDフリップフロップではCE入力が0のときにはいくらエッジが来ても出力Qは変化しない。CEが1の時のクロックの立ち上がりエッジでD入力からのデータを取り込み、出力Qへ反映する。
内部回路を以下に示す。クロック入力を抑制するにはCLKにANDゲートを挿入する方法もあるが、完全同期式回路ではフリップフロップのCLKにゲートを挿入することは禁止される。
代わりに、以下の図のようにフリップフロップの入力Dの前に幾つかのゲートを挿入する。
外部入力CEにより、現在のQの出力値を保持するか、外部入力Dからの値を取り込むか選択するようになっている。マルチプレクサはS0=0のとき、Q=D0、S0=1の時はQ=D1となる。 以下にverilogのコードを示す。
module DFFE_VERILOG(SW0, SW1, SW2, LED0); input SW0; input SW1; input SW2; output LED0; reg LED0; always @(posedge SW0) begin if (SW1 == 1'b1) begin LED0 <= SW2; end end endmodule
セットリセット
フリップフロップに保持されている値を強制的に1あるいは0にするための制御入力がそれぞれセット、リセットである。Dフリップフロップを例にセット入力端子Sとリセット入力端子Rを追加した回路シンボルと内部回路を以下に示す。
verilogのコードを以下に示す。
module DFFERS_VERILOG(SW0, SW1, SW2, SW3, SW4, LED0); input SW0; input SW1; input SW2; input SW3; input SW4; output LED0; reg LED0; always @(posedge SW0) begin if (SW == 1'b1) begin LED0 <= 1'b0; end else if (SW2 == 1'b1) begin LED0 <= 1'b1; end else if (SW3 == 1'b1) begin LED0 <= SW4; end end endmodule
クロックイネーブル/セットリセット付きトグルフリップフロップ
クロックイネーブルやセットリセットの機能についてはDフリップフロップに限られず、他のフリップフロップにも追加できる。また、クロックイネーブル機能とセットリセット機能は同時に追加できる。以下はクロックイネーブル/セットリセット付きトグルフリップフロップの回路シンボルと内部回路である。
verilogのコードを示す。
module TFFERS_VERILOG(SW0, SW1, SW2, SW3, LED0); input SW0; input SW1; input SW2; input SW3; output LED0; reg LED0; always @(posed SW0) begin if (SW1 == 1'b1) begin LED0 <= 1'b0; end else if (SW2 == 1'b1) begin LED0 <= 1'b1; else if (SW3 == 1'b1) begin LED0 <= ~LED0; end end endmodule
制御端子の優先順位はリセットが最優先で、次にセット、クロックイネーブルと続き、トグル入力は最も優先順位が低くなっている。
完全同期式回路
複数のフリップフロップを用いる場合、気をつけなければならないのが、クロックスキューだ。以下の回路のようにすべての順序回路の状態変化が同時に起こる回路を完全同期式回路という。こうすることで、すべての回路の0,1の変化がクロックに同期して起こるため、1クロックを単位とした時間の概念を回路設計に取り入れることができる。
2つのDフリップフロップの例
以下に2つのDフリップフロップを直列接続した回路を示す。
D1に入力される信号は1クロック遅れてD2に入力され、さらに1クロック遅れた信号がQ2から出力される。 D1に入力されるパルスは2番めのパルスの立ち上がりで最初のDフリップフロップに取り込まれる。FD1の出力であるD2は直後に1を立ち上がる。この時後段のフリップフロップは2番めのクロックの立ち上がりで、D2の状態を取り込むが、このとき D2はまだ0であるため、FD2には0が取り込まれ、出力Q2は0のままだ。 FD2に1が取り込まれるのは3番めのクロックの立ち上がりで、3番めのクロックが立ち上がるとき、D1は0となっているので、FD1には0が取り込まれ、直後にD2は0に立ち下がる。しかし、同時にFD2がD2の状態1を取り込むので、直後に出力Q2が1となる。
ここで、注意すべきはD2の信号で、特性が同一の2つのDフリップフロップに全く同じタイミングで立ち上がるクロック信号が入力されているため、状態が変わる直前の状態が取り込まれている。
しかし、この動作が保証されるためには2つの条件があり、1つはセットアップ時間を満たしているかということ。前段のDフリップフロップの出力は必ずクロックの立ち上がりで、遷移するので、後段のDフリップフロップに入力される信号は1つ前のクロックの立ち上がりから、遷移するまでの遅れ時間TCKO経過してから確定している。
もう一つはホールド時間を満たしているかということで、前段のDフリップフロップの出力は、クロックの立ち上がりから、状態遷移するまでに遅れ時間がある。この遅れ時間が、後段のDフリップフロップの入力のホールド時間より長くなければならない。
FPGAにはクロック供給用にスキューが小さくなるように設計されたグローバルラインと呼ばれる専用配線がある。XilinxのFPGAではBUFGというプリミティブで使用できる。また、外部のオシレータ等をこのグローバルラインに接続するには、専用のGCLKというピンと、IBUFGというプリミティブを使用する必要がある。
カウンタ
2bitバイナリカウンタの内部回路を以下に示す。最初のトグルフリップフロップは2分周回路となり、後段のトグルフリップフロップはQ0=1の時にクロックの立ち上がりで値を反転させるので、出力Q1の信号周波数はQ0の更に1/2、つまり入力クロックの1/4の周波数となる。結果、入力をCLK、出力をQ1とした時、本回路は4分周回路となる。
更にトグルフリップフロップを追加して、以下の様な回路を作ると、出力Q2はクロック信号の1/8、出力Q3は1/16の周波数となる。 ここで、出力Q0をLSB、Q3をMSBとして、Q0〜Q3を4bitのデータとして捉えると、0000b〜1111bまでクロックの立ち上がりが来るごとにインクリメントしていることがわかり、このように出力が2進数となっているカウンタをバイナリカウンタという。
最後に、2bitバイナリカウンタ、4bitバイナリカウンタのverilogコードを示す。
module CB2_VERILOG(CLK, Q); input CLK; output [1:0] Q; reg [1:0] Q; always @(posedge CLK) begin Q <= Q + 1'b1; end endmodule
module CB4_VERILOG(CLK, R, CE, Q, TC, CEO); input CLK; input R; input CE; output [3:0] Q; output TC; output CEO; reg [3:0] Q; always @(posedge CLK) begin if (R == 1'b1) begin Q <= 4'd0; end else if (CE == 1'b1) begin Q <= Q + 1'b1; end end assign TC = &Q; assign CEO = &Q & CE; endmodule
FPGA入門 備忘録③ ~組み合わせ回路編~
備忘録②の続き。
加算回路
半加算器
2進数の足し算は、
0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 10
と書ける。これの足される数を入力A、足す数を入力B、その桁の加算結果を出力S、桁上りを出力COとして真理値表で示すと、以下のようになる。COは桁上りが生じたかどうかを表すビットである。
A | B | S | CO |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 1 |
この真理値表から回路を構成すると以下のようになる。
この加算回路は下の桁からの桁上りを考慮しておらず、下からの桁上りがない最下位ビットのみにしか使えない。これを半加算器という。
全加算器
桁上りが生じたかどうかを表す出力COは2桁目以降、そのまま加算すればよい。この下からの桁上りを考慮して半加算器に、ビットの入力を追加した加算回路を全加算器と呼ぶ。以下に全加算器の真理値表と回路図を示す。
A | B | CI | S | CO |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 | 1 |
次に、全加算器を用いた3bit加算回路の回路図を見てみよう。
変数 | 変数の各ビット | 信号名 |
---|---|---|
被加数 | A0 (LSB) | SW0 |
A1 | SW1 | |
A2 (MSB) | SW2 | |
加数 | B0 (LSB) | SW3 |
B1 | SW4 | |
B2 (MSB) | SW5 | |
演算結果 | S0 (LSB) | LED0 |
S1 | LED1 | |
S2 (MSB) | LED2 | |
桁上げ出力 | CO | LED3 |
AとBを加算し、LEDに出力する回路になっている。これをverilogで書くと、
module FA3_VERILOG(CO, S, A, B); input [2:0] A; input [2:0] B; output CO; output [2:0] S; assign {CO, S} = A + B; endmodule
assign {CO, S} = A + Bのところだが、まず左辺はCOは1bitで、Sは3bit、合計で4bitである。右辺は3bit同士の論理和で4bitになる。
減算回路
半減算器
2進数の引き算は、
0 - 0 = 0 0 - 1 = 11 1 - 0 = 1 1 - 1 = 0
と書ける。これの足される数を入力A、足す数を入力B、その桁の加算結果を出力S、桁上りを出力COとして真理値表で示すと、以下のようになる。BOは桁借りが生じたかどうかを表すビットである。
A | B | D | BO |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 0 |
この真理値表から回路を構成すると以下のようになる。
この減算回路は下の桁への桁下がりを考慮しておらず、下への桁下がりがない最下位ビットのみにしか使えない。これを半減算器という。
全減算器
以下に全減算器の真理値表と回路図を示す。
A | B | BI | D | BO |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 | 1 |
0 | 1 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 0 |
1 | 1 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 |
図は省略するが、加算器と同様に3bit減算回路のverilogは
module FS3_VERILOG(A, B, BO, D); input [2:0] A; input [2:0] B; output BO; output [2:0] D; assign {BO, D} = A - B; endmodule
と書ける。
負の数
減算結果の負の数を2進数で表す場合、最も単純なのは符号を表すビットを追加して、符号ビット+絶対値として表す方法だ。符号ビットは正の時に0、負の時に1とする。つまり、-2dは値を3bitとすれば、1010bと表せる。3bitの絶対値に符号ビットを追加して表現した例を以下に示す。
10進数 | 符号なし2進数 | 符号付き2進数 |
---|---|---|
15 | 1111 | - |
14 | 1110 | - |
13 | 1101 | - |
12 | 1100 | - |
11 | 1011 | - |
10 | 1010 | - |
9 | 1001 | - |
8 | 1000 | - |
7 | 0111 | 0111 |
6 | 0110 | 0110 |
5 | 0101 | 0101 |
4 | 0100 | 0100 |
3 | 0011 | 0011 |
2 | 0010 | 0010 |
1 | 0001 | 0001 |
0 | 0000 | 0000 or 1000 |
-1 | - | 1001 |
-2 | - | 1010 |
-3 | - | 1011 |
-4 | - | 1100 |
-5 | - | 1101 |
-6 | - | 1110 |
-7 | - | 1111 |
先ほどの3bit減算回路の演算結果出力と比べてみる。
減算結果(10進数) | 出力パターン | 符号付き2進数 |
---|---|---|
BO,D2,D1,D0 | 符号1bit,絶対値3bit | |
7 | 0111 | 0111 |
6 | 0110 | 0110 |
5 | 0101 | 0101 |
4 | 0100 | 0100 |
3 | 0011 | 0011 |
2 | 0010 | 0010 |
1 | 0001 | 0001 |
0 | 0000 | 0000 or 1000 |
-1 | 1111 | 1001 |
-2 | 1110 | 1010 |
-3 | 1101 | 1011 |
-4 | 1100 | 1100 |
-5 | 1011 | 1101 |
-6 | 1010 | 1110 |
-7 | 1001 | 1111 |
3bit減算回路の出力パターンと符号付き2進数を比較すると、減算結果が正の時は一致しており、また負の時もBOと符号ビットは一致している。つまり、減算結果が負となる時のD2,D1,D0の3bitの絶対値部分を変換すれば良い。この変換には補数を用いる。具体的には、
-まず、D0〜D2の各ビットを反転 -次に反転した3bitのDに1bを加算
のように行う。表で変換過程を示すと以下のようになる。
減算結果 | 出力パターン | D0〜D2を反転 | さらに1を加算 |
---|---|---|---|
(10進数) | BO, D2, D1, D0 | BO, ~D2, ~D1, ~D0 | BO, (~D2, ~D1, ~D0)+001b |
-1 | 1111 | 1000 | 1001 |
-2 | 1110 | 1001 | 1010 |
-3 | 1101 | 1010 | 1011 |
-4 | 1100 | 1011 | 1100 |
-5 | 1011 | 1100 | 1101 |
-6 | 1010 | 1101 | 1110 |
-7 | 1001 | 1110 | 1111 |
各ビットを反転して1bを加算する回路は補数機と呼ばれており、以下の様な回路で示される。
本では最後に、補数機を3bit減算器に組み合わせ符号付き2進数3bit減算回路を示している。回路図は省略するが、verilogだけ書いておく。
module FS3_SIGN_VERILOG(A, B, BO, D); input [2:0] A; input [2:0] B; output BO; output [2:0] D; wire [3:0] sub; assign sub = {1'b0, A} - {1'b0, B}; assign BO = sub[3]; assign D = sub[3] ? (~sub[2:0] + 1'b1) : sub[2:0]; endmodule
今回はここまで。次回は順序回路から。
FPGA入門 備忘録② ~基本回路、組み合わせ回路編~
備忘録①からの続きになる。なお本では前回と今回の間にXilinxのISEのインストール方法、回路図エディタの使用方法などが記されている。
論理素子
まずは基本的なところから、VHDLとverilogの記法の違い。
名称 | 機能 | VHDL | Verilog HDL |
---|---|---|---|
NOTゲート(インバータ) | 論理反転 | not | ~ |
ANDゲート | 論理積 | and | & |
ORゲート | 論理和 | or | | |
XORゲート | 排他的論理和 | xor | ^ |
NANDゲート | 否定論理積 | nand | なし |
NORゲート | 否定論理和 | nor | なし |
XNORゲート | 否定排他的論理和 | xnor | ~^ |
自分の目的はVerilog HDLを使いこなせるようになることなので、VHDLについては以後触れない。 さて、本の中では以下の様な回路を回路図エディタ、VHDL、Verilog HDLの3種類で作成することを試みている。
module INV_VERILOG(PSW0, LED0); input PSW0; output LED0; assign LED0 = ~PSW0; endmodule
assign LED0 = ~PSW0;という記述の~がNOTゲートを表している。LED0が出力で、PSW0が入力で、PSW0をインバートしたものがLED0に接続されているということだ。
ANDゲート
VerilogではANDゲートを
assign Q = A & B;
と表し、VHDLでは、
Q <= A and B;
と表す。 これを踏まえて、SW1とSW2の両者が入力されると、LED0が点灯するようなverilog のコードを書いてみよう。
module AND_VERILOG(SW0, SW1, LED0); input SW0; input SW1; output LED0; assign LED0 = SW0 & SW1; endmodule
ORゲート
VerilogではORゲートを
assign Q = A | B;
と表し、VHDLでは、
Q <= A or B;
と表す。
XORゲート
VerilogではXORゲートを
assign Q = A ^ B;
と表し、VHDLでは、
Q <= A xor B;
と表す。
NANDゲート
VerilogではNANDゲートを
assign Q = ~(A & B);
と表し、VHDLでは
Q <= A band B
と表す。verilogではAとBのANDを括弧でくくりそれをNOTすることでNANDを表現している。
NORゲート
VerilogではNORゲートを
assign Q = ~(A | B);
と表し、VHDLでは
Q <= A nor B;
と表す。verilogではAとBのORを括弧でくくりそれをNOTすることでNORを表現している。
XNORゲート
VerilogではXNORゲートを
assign Q = A ~^ B;
と表し、VHDLでは
Q <= A xnor B;
と表す。
組み合わせ回路
上でも示したように、NANDゲートはANDゲートとNOTゲートを接続して作成できる。つまり、ANDゲートとNOTゲートによる組み合わせ回路といえる。NORゲートも同様にORゲートとNOTゲートの組み合わせで作成できる。では、ANDやOR、NOTゲートはどうだろう。実はこれもNANDゲートで作ることが可能だ。以下の図はそれぞれNANDゲートのみで構成したNOTゲート、 ANDゲート、ORゲートだ。
また、XORはAND、OR、NOTを組み合わせれば構成できるので、NANDで置き換えることが可能だ。
HDLの3つの記述方法
HDLにはいくつかの記述方法があり、回路によって記述しやすいものを使用する。記述方法は大きく3つあり、
- 論理演算子を組み合わせて記述する方法
- テーブルを用いる方法
- プリミティブを直接指定する方法
にわけられる。それぞれXOR回路を例に順に見ていく。
論理演算子を組み合わせて記述する方法
module XOR1_VERILOG(A, B, C); input A; input B; output C; assign C = ~(~A & ~(B & B)) & (~(~A & A) & B))); endmodule
上の回路図と合わせて見ると理解できると思う。
テーブルを用いる方法
テーブルとは真理値表のことで、より複雑な論理を記述するのに向いている。テーブルの記述にはいくつかの方法があり、VHDLではwith select、case文を用いて、Verilogではassign、case文を用いて書く方法がある。 まずはassignを用いて書いた場合を見てみよう。
module XOR2_VERILOG(A, B, C); input A; input B; output C; wire [1:0] Q; assign Q = {A, B}; assign C = (Q == 2'b00) ? 1'b0 : assign C = (Q == 2'b01) ? 1'b1 : assign C = (Q == 2'b10) ? 1'b1 : assign C = (Q == 2'b11) ? 1'b0 : 1'b0; endmodule
まずwire宣言から。これは2bit幅のバスラインQを宣言している。 assign Q = {A, B}でQの上位ビットをAに、下位ビットをBに接続している。 次に、assign C = (Q==2b'00) ? 1'b0 :で、Qの値が00であれば、Cに0を出力する事を指定している。最後の1'b0はCのデフォルト値で、Qの値が未指定の場合の出力値を0としている。
次に、case文で記述したものを見てみる。
module XOR3_VERILOG(A, B, C); input A; input B; output C; reg C; wire [1:0] Q; assign Q = {A, B}; always @(Q) begin case (Q) 2'b00: C = 1'b0; 2'b01: C = 1'b1; 2'b10: C = 1'b0; 2'b11: C = 1'b0; default: C = 1'b0; endcase end endmodule
Cはalways文の中で使用するので、reg C;と宣言する必要がある。always文については長くなるので後回し。
プリミティブを直接指定する方法
各デバイス特有の回路を、直接指定する際に使用する。したがって、指定できるプリミティブはデバイスによって異なる。FPGAごとに使えるライブラリのガイド一覧はXIlinxのHPで公開されている。 verilogでXOR2プリミティブを直接呼ぶ例を見てみよう。
module XOR4_VERILOG_TOP(A, B, C); input A; input B; output C; XOR2 instance1(.O(C), .IO(A), .I1(B)); endmodule
instance1という名前のXOR2に各信号を接続している。カッコ内の.O(C)という記述はXOR2の出力ピンOと外部出力ピンCが接続されることを意味する。ここの信号名OやIOなどはライブラリガイドに則った名称である必要がある。
マルチプレクサ
実用的な組み合わせ回路の一例としてマルチプレクサを取り上げる。マルチプレクサの真理値表は、
D0 | D1 | S0 | O |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
右図で示すようにマルチプレクサはS0が0の時はO=D0となり、1の時はO=D1となる。つまり、Oに出力するデータを、S0によって選択する回路となっている。
1bit2入力マルチプレクサの内部回路を見てみよう。
S0=0の時は、D0側のANDゲートがアサート(EN)され、D1側はネゲート(Disable)される。逆に、S0=1の時はD0側のANDゲートがネゲートされ、D1側のANDゲートがアサートされる。
これは、S=1の時にスイッチが押されて、DOにDINの値が出力され、S=0の時はスイッチが切り離され、DOが0となると考えられる。verilogでは以下のように書ける。
module M2_1_VERILOG(D0, D1, S0, 0); input D0; input D1; input S0; output O; wire d0_sel; wire d1_sel; assign d0_sel = D0 & ~S0; assign d1_sel = D1 & S0; assign O = d0_sel | d1_sel; endmodule
デコーダ(デマルチプレクサ)
マルチプレクサの対になるのが、デマルチプレクサである。デマルチプレクサは一般にデコーダとして使われることが多く、ここでは2進数のデータを10進数に戻すバイナリデシマルデコーダを指している。 2bitバイナリデシマルデコーダの真理値表を以下に示す。
A1 | A0 | E | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|
- | - | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 0 | 0 | 1 |
0 | 1 | 1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 | 0 | 0 |
1 | 1 | 1 | 1 | 0 | 0 | 0 |
E=1の時、Aに入力されるバイナリコードに応じて、出力Dのいずれかが1となる。出力Dは最下位ビットから順にD0=1、D1=2、D2=3、D3=4という形で、10進数を表している。 ここで、E=0の時は入力Aに関わらず、出力D0〜D3はすべて0になる。したがって、Aで選択した出力先のDの値はEの入力値に等しくなる。Eをデータ入力、Aを制御入力と考えると、Eの出力先を切り替える回路として利用できる。これはマルチプレクサと逆の動きなので、デマルチプレクサと呼ぶ。
Eをデータ入力として、Aを制御入力として使うものがデマルチプレクサで、Aをデータ入力とし、Eは制御入力(EN端子)として使うものがデコーダとなる。
2bitバイナリデシマルデコーダの内部回路は以下のようになっている。
Eをデータ入力とした時、A0及びA1で4つのANDゲートのいずれかをアサートする選択回路となっていることが分かる。verilogのコードも示す。
module D2_4E_VERILOG(A0, A1, E, D0, D1, D2, D3); input A0; input A1; input E; output D0; output D1; output D2; output D3; assign D0 = E & ~A0 & ~A1; assign D1 = E & A0 & ~A1; assign D2 = E & ~A0 & A1; assign D3 = E & A0 & A1; endmodule
とりあえずは、ここで今回は終わり。備忘録③は加算回路から。
鮨ます田に行ってきた
STARTUP HARDTHINGS@ASACに行ってきた
STARTUP HARDTHINGSというスタートアップ系の勉強会に行ってきた。 会場は青山にあるASAC(Aoyama Startup Acceleration Center)という場所。 なんでも東京都が借り上げている施設で、施設運営を監査法人のトーマツが行っているらしい。
会場の写真は撮影しなかったのだが、イベントを催した場所の広さは大きめの会議室程度。 定員50名に対し、申し込みが75名ほど。実際に来たのは40名といったところか。
講演内容
トーマツの方が司会進行を務め、それに対し、座談会形式で話していくスタイルで行われた。 まずは登壇者3名のプロフィールから。
登壇者紹介
- 真子就有氏(株式会社div 代表取締役) プログラミング教育事業TECH::CAMPが主な事業
- 浅枝大志氏(Beatrobo Inc. CEO) スマホのイヤホンジャックに挿すだけで音楽や動画が楽しめるPlugAirが主な事業
- 天沼聰氏(株式会社エアークロゼット 代表取締役CEO) 洋服のシェアリングサービスAirClosetが主な事業
トークセッション
〜立ち上げ時の苦労に関して〜
(真子氏)自分は学生時代からITベンチャーで働いていた。大学4年の時に「じげん」という会社で人事をやっていた。5名内定者出した時点で自分が起業したくなった。社長には怒られた。やめる時が大変だった。やめる時がHARD THINGSだった。
-皆さん会社のやめ方は?
(真子氏)Gmailで上長に3日間ぐらい推敲したメールを送った。Bccに地元の友達入れてたw 上長とは普通に面談。社長に怒られた。
(浅枝氏)もともと就職したことない。ちなみに就活では電通と任天堂だけ受けた。電通は面接で第二希望です!と正直に行ったら落ちた。任天堂は大学院に生きながら働けますか?京都に行くのは嫌です、と言ったら落ちたw
(天沼氏)前職は楽天だった。やめるときは上司呼んで話した。もともと上司には起業志望であること話していたのでスムーズにやめられた。 楽天に移ってからは新規プロジェクトをワンサイクル回して、後継のマネージャ採用まで行ったので、引き継ぎはしっかりした。
-在職中に準備していた?
(天沼氏)在職中は楽天からお金をもらっているので、片手間でやることはしなかった。 楽天をやめた時点でairclosetのビジネスモデルはまだ概念レベル。
-皆さんサービス作る時の最初の構想は?
(浅枝氏)世界で俺しかこのサービス作れないというのが自分の基準。他の誰かが既にやっているものには興味が無い。VRとかみんなやってるから俺はいいやという感じ。 (真子氏)ひとつ目のサービスはlogというサービスをやっていた。Facebookは人間関係を可視化したから、興味を可視化したいと思った。しかし、実際にはただの記録ツールで、コミュニケーションが生まれておらず想定の使い方と違った。 そこでコミュニケーションの機能をつけた(logcomm)。チーム全員行けると思っていたけど、1ヶ月後キャッシュアウト。 Classというサービスもバズった。意外とやってみると、めっちゃ緊張する。青春時代の思い出補正で勘違い→なんか違うで怒ってる人が多かったw あとはActiveUser1000人くらいの時にiOSアプリでバグ、炎上。
-こういう世の中になる、その確信は?
(浅枝さん)なかなかそういう時は来ない。セカンドライフが3Dインターネットの走りでそういう世の中になると思った。 VRのなかで、空間の中で人に合う時代が来る。アバターの時代が来る。
-未来予想図はどう立ててる?
(浅枝さん)映画とか参考にしてる。攻殻機動隊、サマーウォーズ、ドラえもん、、、等々。
-未来予測はできる?
(天沼さん)できないと思う。シェアリングエコノミー、ライフスタイルに浸透、インターネットが好き、その軸。 コンサル3人で起業したので、評価軸とかで100個ぐらいのビジネスモデル比較して、、、最終的には感情で決めた。 今の課題を5年10年先で、どうしたいか。具体的なビジネスモデルは手前のもの。
(浅枝さん)CEOは2種類いるとおもう。事業家か芸術家。真子さんは芸術家、天沼さんは事業家。
(真子さん)うまくハイブリッドさせたいとは思ってるんですけどね。
~チーム作りについて~
(真子さん)共同創業者は二人。俺は一人でもやるけど、お前やるならやってもいいよ。普通株式も9割社長が鉄板だが、55%、45%とかにした。共同創業者は株主間契約をしておいたほうがいい。
(天沼さん)自分はやっている
(浅枝さん)自分もやった。資本政策は一番躓くところ。
-浅枝さんはチーム作りどう?
(浅枝さん)自分はロマンを求めた。セカンドライフの会社は一人でやってた。次は3人で33.3%としてたけど、金が入る前に50.1%を俺にくれと交渉。株主間契約やった。結婚みたいなもの。
(真子さん)つい渡したくなる気持ちは出てくる。不公平だから、こいつは俺より優秀だし、、等々 1000億とかの会社を作るのなら、2割でも5割でも関係ないと思う。
(浅枝さん)芸術家はお金を気にしない。
(天沼さん)株主比率にこだわって、資金調達が遅れるぐらいなら、下がっても良いと思っている。 あと、仲間の二人には役員報酬がゼロだったとしてもできるかを聞いた。 丸一年だったらできるとの返答。全面的に信頼できるメンバー、かつ金銭的に答えが返ってきたので一緒にやることにした。 創業メンバーは3人にこだわる。二人だと対立する。第3社的な視点が必要。
(真子さん)二人はまずい。上下関係もできたりする。
質疑応答
-外注と内製等何を優先すべきか?
(天沼さん)いまは全部内製。
(真子さん)優位性がなにか、という点。toCの場合、使い方。toBの場合、まずは外注。そのほかは営業に回るなど。
(天沼さん)改善を繰り返す必要があったので、サービスの質、スピードのどちらを重視するか?
(天沼さん)スピードをとる。やってみないとわからない。外注していると改善のスピードを高められない
(真子さん)作りこんでリリース、ドンズべりはある。以下に作らないかが勝負。
(天沼さん)最初はファッション業界の知り合いゼロだった。Facebookに投稿して、ファッション業界の知り合い紹介して、ってお願いして一人づつ増やしていった。
(天沼さん)組織づくりは企業に入っていると参考になる。
-採用に関して、一緒に働きたい以外の軸はあるか?
(天沼さん)グループ長の人が採るといったら基本的には採る。ほかは、キャラがチームに合うか、地頭ロジカルか、情熱があるか どういう人間になりたいか、も自分は聞く。
(浅枝さん)うちをやめたらあなたはどうなっていますか?という質問をする。
-自分より優秀な人を採用するのはどうやる?
(天沼さん)優秀かどうかって難しい。会社って役割がそれぞれあって、優秀さの判断をしない。
(浅枝さん)その人の部下になっても良いかを聞く
(真子さん)リファレンスは必ず取るようにしてる
(浅枝さん)あえて短所は?などと聞く
(真子さん)ここで働くこと自体が最高なんだ、そこがぶれない事が大事。
(天沼さん)伝え続けること大事
-一緒にできるか、の基準は何か?
(天沼さん)金銭的な部分をきちんとくぐり抜けられるか。ディスカッションを夜通しやっていても疲れないか。
-サービスが立ち上がらない。
(天沼さん)サービス価値が何か、言えることが重要。あれも解決できるし、これも、、となっている。できるかぎりシンプルに答えられることが重要。誰のために、は重要。 会議もSlackもお客さんが一人聞いていると思え、と言っている。slackでも顧客は呼び捨てにしない。
-資金調達を決断するタイミングは?
(天沼さん)株主になると一定の権利が生まれる。エンジェルの場合、VCに比べ、感情がかなり入る。
(浅枝さん)出資を受けずに上場するのが一番良い。リブセンスの例もある。
感想
登壇者の皆さんについて多くは知らなかったが、参考になることは多かった。やっぱり実務をやっている人の話は面白い。Slackはお客さんが見てると思って書き込めはいいな。
R勉強会@ORACLEに行ってきた
ORACLEオフィスに入ってみたかったのと、家の近所ということもあり、(もちろんRや機械学習に興味があるのもあり)R言語勉強会に行ってきた。本記事はその備忘録。 oracleclouddevelopers.doorkeeper.jp
講演資料
1.Rのインストール
Rはcranさえみておけばどうにでもなる。cranに全ての情報が集まっている。 cranからダウンロード・インストール。Windows/Macともにこれは特に躓くことはないと思う。 ちなみにOracle社内ではWindows/Macのユーザ比率は半々行かないくらいらしい。
2.Rとは?
Rとはプログラミング言語であり、環境である。関数型言語件オブジェクト指向言語。GNUライセンスで無償で再配布可能。Rの強みは大量のライブラリ。金融業界でライブラリが充実。ブラック・ショールズ式が一行で書けたりする。保険業界、金融業界向けライブラリなど充実。 Java/C/C++/Python/C#につぐ順位。 OracleのDistributionもある。intel mklも使える!
3.Rの基本(変数と処理とデータ構造)
この辺りからハンズオン。 起動は普通にSpotlight検索でRと打てば起動できる。 =はパッケージの引数とかに使うので通常の代入は<-を使う。 使い方なので、slideshareを見ながら進めれば良い。 piは予約語。 ベクトルとして扱ってるが、要は配列。この辺は楽勝。なお、c(1:10)などとするのが正規の方法だが、単に1:10でも良い。 ベクトルは変数の型が1種類だったが、複数の型が使われている場合、データフレームを使う。データフレームを抽出する記法がいくつかあるけど、Rを知らない人には可読性ない感じ。なお、コマンドの途中で改行すると+と表示される。
> df <- data.frame(ID = c(1:3), Name =c("John","Bob","Mike"))
4.Rにcsvファイルを読み込む
ここからデータを取ってくる。UCI Machine Learning Repository というのはML系を使うのに便利。IoT系やりたいんだけど、、→検索するとセンサデータ出てくる。さらにそのデータを使ったMLの世界はまず論文を検索してやってみる世界。
Rに戻って、getwd()でRのカレントディレクトリを取得し、そこにファイルを置く。そして、
> df_default <- read.table("creditdefault.csv",skip = 1,header = T,sep = ",") > summary(df_default)
summary()関数で列データ等の集計を一瞬でできる。
5.Rでグラフ描写
グラフの描画はggplotがデファクトで、皆こっちを使ってるらしい。 各セッションごとに、各ライブラリを読み込まないといけない。 ggplotの描画はレイヤごとに行うイメージ。
> library(ggplot2) > base1 <- ggplot(df_default,aes(x = EDUCATION, y = MARRIAGE)) > base1 > points1 <- base1 + geom_bin2d() > points1
- アプリケーションの中に組み込みたい場合→Pythonが向いている
- 分析が主→Rが向いている
6.Rで機械学習を使って予測モデル作成
indexes <- sample(1:nrow(df_default),size=0.4*nrow(df_default))
上記コマンドはテスト用の30000行のデータのうち4割、学習用に6割を割り当てる。このような書き方は定番。 決定木用のライブラリはRがデフォルトで持っている。 ランダムフォレストでほぼDeepLearning並の精度が出ることもある。レコメンドエンジンなどもこれで動いていたりする。ランダムフォレストは決定木をデフォルトで500本作る。
7.Oracle R Enterpriseデモンストレーション
OracleデータベースにあるデータをそのままRで処理できる。時間が足りなくて、デモはスキップw。
まとめ
- 素晴らしいハンズオンであった。2時間と短時間ながら、予定した項目を網羅。置いてきぼりの人は殆どいなかったのではないか。
- WEB系の勉強会とは異なる参加者属性。金融系や保険系のプログラミング学習者が多くいる。
- ML系のデータセットの情報聞けたのは良かった。
おまけ
- ドリンクが無料だった。大手町のMSの研修センターといい外資系は気前がよいw
FPGA入門 備忘録① ~準備編~
FPGA入門という本を買った。この記事はその本の内容の備忘録。
回路図で学べるFPGA入門 回路図は読める人のためのHDLガイド
- 作者: すすたわり
- 出版社/メーカー: 秀和システム
- 発売日: 2016/03/25
- メディア: 単行本
- この商品を含むブログ (1件) を見る
1.FPGAとは
FPGA(Field Programmable Gate Array)は書き換え可能な集積回路。
どのように書き換え可能かというと、予め必要と思われる回路を用意しておいて、必要なものをスイッチなどで切り替えて使用する。予め用意しておく回路は、AND、OR、NOTなどの基本ゲート。構成としては、
- アンチヒューズ型
- SRAM型
などがある。
アンチヒューズ型は図(a)のように配線したい部分の絶縁体を物理的に壊すことで任意の回路を実現する。物理的に結線されるため信号の遅延が少なく、高速な動作が可能。しかし1回しか書き込めない。
図(b)は切替スイッチをもちいて論理回路を切り替えることを考える方法。マルチプレクサがどの論理ゲートを選択するかはメモリに書き込む情報で決定される。
しかし、これだけでは切り替え機構を追加した分、アンチヒューズ型に比べ、回路規模が大きくなってしまう。
そこで、実際のSRAM型FPGAではより面積効率の高いLUT(Look Up Table)を使った構成になっている。図(c)のようにRAMのアドレス入力をデータ入力端子として用いることで、必要な論理演算結果を得る。具体的に(c)のケースではAB端子によってAddressが指定され、OR演算に対応するDataが出力される。これによりこのSRAMはORゲートとして機能する。(d)は4入力NANDのケースだ。
FPGAではこのようなLUTの他にフリップフロップなどの基本セルなどからできている。各基本セルの間には、基本セル同士を接続するための配線とスイッチが並んでいる。
2.開発準備
FPGA開発には、
- 開発用PC
- 開発ソフト
- FPGAボード
- ダウンロードケーブル
が最低限必要になる。
開発ソフト
開発ソフトとしては各社以下のソフトを用意している。
社名 | 開発ソフト名 |
---|---|
Xilinx | ISE |
Altera | Quartus |
Lattice | Diamond |
FPGAボード
次に FPGAボードを用意しなければならない。
各社のFPGAチップの製品ファミリーラインナップは以下のようになっている。
社名 | 製品名 | 用途 |
---|---|---|
Xilinx | Spartan | 低コストFPGA |
↑ | Zynq | ARM Cortex内蔵のFPGA |
↑ | Artix | 低電力でコスト重視のアプリケーション向け |
↑ | Kintex | 低電力でコスト効果の高い信号処理アプリケーション向け |
Altera | Stratix | ハイエンドFPGA |
↑ | Arria | ミドルレンジFPGA |
↑ | Cyclone | 低コストFPGA |
↑ | Max | 電源を入れたら即起動のFPGA |
Lattice | ECP | 低コストファミリーFPGA |
↑ | iCE | モバイル用FPGA |
↑ | Mach | 高信頼性、低コストを備えるFPGA |
個人用途でFPGAを使う場合、あまり高価なものは買えない。ボードそのものの値段も高い上、高速なインターフェースに対応した各種測定器等を個人でそろえるには相当に困難だからだ。例えば、オシロスコープ一つでも高速なものでは1000万円以上する。差動プローブなども一つで軽自動車一台買える値段のものもざらだ。
Xilinxの場合、Spartanが載ったFPGAボードが個人用途の選択肢となる。
ダウンロードケーブル
次に以外に厄介なのがダウンロードケーブルだ。Xilinxの公式ケーブルが一番良い選択肢だが高い。Amazonでは4万円もする!
次がDigilent社製の互換品で、こちら。Amazonでは3万円だが、探せば2万円程度のショップもある。
最後が、特殊電子回路社製のJ-Writerを使うケース。この場合、上記二つより安価で、しかもAlteraのCycloneやLatticeのXP2などXilinx社以外にも対応している。ただ、XilinxのiMPACTからは使用できず、専用のソフトを使う必要がある。
開発統合ソフト
開発ソフトもFPGA開発には必要だ。Xilinxの場合、ISE(Integrated Software Environment)がそれにあたる。
そもそもFPGAのデザインフローは
- 回路設計
- ピンアサイン
- 論理合成
- インプリメンテーション
- ダウンロード
という流れで行う。論理合成はHDLからネットリストに変換する工程を指し、インプリメンテーションとはネットリストから実際に使用するFPGA向けのコンフィギュレーションデータまで変換する行程を指す。