From b46a960dee3eb17ca34a7771716e228f402358bc Mon Sep 17 00:00:00 2001 From: "yuki.yahagi" Date: Wed, 30 May 2018 16:26:19 +0900 Subject: [PATCH] =?UTF-8?q?2x2=E3=81=AE=E3=82=A2=E3=83=8B=E3=83=BC?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=B0=E3=83=9E=E3=82=B7=E3=83=B3=E3=81=A3?= =?UTF-8?q?=E3=81=BD=E3=81=84=E3=82=82=E3=81=AE=E3=82=92=E4=BD=9C=E3=81=A3?= =?UTF-8?q?=E3=81=A6=E3=81=BF=E3=81=9F=EF=BC=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...53\343\201\244\343\201\204\343\201\246.md" | 9 +- semi_annealing_2x2/annealer_2x2.v | 128 ++++++++++++++++++ ...53\343\201\244\343\201\204\343\201\246.md" | 3 + 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 semi_annealing_2x2/annealer_2x2.v create mode 100644 "semi_annealing_2x2/annealer\343\201\253\343\201\244\343\201\204\343\201\246.md" diff --git "a/kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" "b/kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" index b77d4a0..a20db74 100644 --- "a/kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" +++ "b/kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" @@ -17,4 +17,11 @@ kenbaiki_TB.v : *kenbaiki.vのテストベンチ* input clk, reset_N; //クロック信号とリセット信号の入力 -このように,何を入力で与え,それぞれのビット幅がいくつになるのか,それぞれのビットは何を表すのかをきちんと決めることが設計で重要になってくる. \ No newline at end of file +このように,何を入力で与え,それぞれのビット幅がいくつになるのか,それぞれのビットは何を表すのかをきちんと決めることが設計で重要になってくる. + +## ブロッキング代入とノンブロッキング代入について +verilogだと,代入文が "=" と "<=" の二種類ある. + +"="がブロッキング代入で,ファイルの上から順番に代入をしていく逐次処理の構文,"<="がノンブロッキング代入で,代入したい値が変化したら即座に代入される. + +assignでは "=" を,always文中では "<=" を使った方がいいのだが,この券売機の例では全部 "=" になっているので注意. \ No newline at end of file diff --git a/semi_annealing_2x2/annealer_2x2.v b/semi_annealing_2x2/annealer_2x2.v new file mode 100644 index 0000000..0a01031 --- /dev/null +++ b/semi_annealing_2x2/annealer_2x2.v @@ -0,0 +1,128 @@ +module annealer_2x2( // 2x2のアニーリングマシン,外部磁場を考えないものとしての実装 + input [3:0] init_spin, // 初期スピン + input [3:0] interact0, interact1, interact2, + interact3, interact4, interact5, + // 相互作用係数,補数表現をする,7 ~ -8の値を取れる,4スピンなので6つ係数がある + // [3:0]がビット幅 + // interact0 <-- spin[0] to spin[1] + // interact1 <-- spin[0] to spin[2] + // interact2 <-- spin[0] to spin[3] + // interact3 <-- spin[1] to spin[2] + // interact4 <-- spin[1] to spin[3] + // interact5 <-- spin[2] to spin[3] + output [3:0] final_spin, // 解となるスピン + input clk, reset_N, start, // クロック,リセット,演算開始,の信号 + output busy // 演算中を表す信号 +); + + reg [3:0] spin; // スピンの値,今回は1, 0で表す(+1 --> 1, -1 --> 0) + reg [3:0] J0, J1, J2, J3, J4, J5; // 相互作用係数 + + reg [6:0] H [4:0]; // ハミルトニアン(エネルギー),相互作用係数から42 ~ -42の値をとるので7ビット必要, + // また,現在の状態 + ある1つのスピンの値が反転した場合の合計5通りの計算をしておく. + reg state_init, state_busy, state_end; + reg invert; // どのスピンを反転させるか + + wire [6:0] Jscale [5:0]; // Jを7ビットに拡張する,7ビットのwireが6本 + wire [6:0] Sscale [3:0]; // スピンの値を7ビットに拡張する,スピンの値を符号ビットのように扱う. + + assign final_spin = spin; + assign busy = state_busy; + + assign Jscale[0] = { { 4{J0[3]} }, J0[2:0] }; // 符号ビットを上位ビット側に4つ並べて拡張している + assign Jscale[1] = { { 4{J1[3]} }, J1[2:0] }; + assign Jscale[2] = { { 4{J2[3]} }, J2[2:0] }; + assign Jscale[3] = { { 4{J3[3]} }, J3[2:0] }; + assign Jscale[4] = { { 4{J4[3]} }, J4[2:0] }; + assign Jscale[5] = { { 4{J5[3]} }, J5[2:0] }; + + assign Sscale[0] = { spin[0], 6'b000000 }; + assign Sscale[1] = { spin[1], 6'b000000 }; + assign Sscale[2] = { spin[2], 6'b000000 }; + assign Sscale[3] = { spin[3], 6'b000000 }; + + always @( posedge clk or negedge reset_N ) begin + if ( !reset_N ) + { state_init, state_busy, state_end } <= 3'b100; + + if ( { state_init, state_busy, state_end } == 3'b100 ) begin + spin <= init_spin; + { J0, J1, J2, J3, J4, J5 } <= + { interact0, interact1, interact2, interact3, interact4, interact5 }; + if (start) + { state_init, state_busy, state_end } <= 3'b010; + + end else if ( { state_init, state_busy, state_end } == 3'b010 ) begin + H[0] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 ) + + ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 ); + // ハミルトニアンの計算,シグマの前の符号は各項に分配している(7'b1000000でXORを取ることで符号を反転させている) + H[1] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ) + + ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ) + + ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ) + + ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 ); + // spin[0]が反転した時を想定したハミルトニアンの計算, + // spin[0]が使われている(Sscale[0]を含む)項の符号を反転させなければ良い + H[2] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ) + + ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ) + + ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ) + + ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 ); + // spin[1]の反転 + H[3] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 ) + + ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ) + + ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ) + + ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 ) + + ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ); + // spin[2]の反転 + H[3] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 ) + + ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ) + + ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 ) + + ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ) + + ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ); + // spin[3]の反転 + + // ハミルトニアンが最小となる反転を見つける. + if( $signed(H[1]) < $signed(H[2]) ) // Hはunsignedなので,キャストしてから比較 + if( $signed(H[1]) < $signed(H[3]) ) + if( $signed(H[1]) < $signed(H[4]) ) + invert <= 1; + else + invert <= 4; + else if ( $signed(H[3]) < $signed(H[4]) ) + invert <= 3; + else + invert <= 4; + else if ( $signed(H[2]) < $signed(H[3]) ) + if ( $signed(H[2]) < $signed(H[4]) ) + invert <= 2; + else + invert <= 4; + else if ( $signed(H[3]) < $signed(H[4]) ) + invert <= 3; + else + invert <= 4; + + if ( $signed(H[invert]) < $signed(H[0]) ) // 反転させた方がエネルギーが小さくなった場合 + spin[invert] <= ~spin[invert]; + else + {state_init, state_busy, state_end} <= 3'b001; + + end else if ({state_init, state_busy, state_end} == 3'b001) begin + {state_init, state_busy, state_end} <= 3'b001; + + end else begin + {state_init, state_busy, state_end} <= 3'b100; + + end + end + +endmodule \ No newline at end of file diff --git "a/semi_annealing_2x2/annealer\343\201\253\343\201\244\343\201\204\343\201\246.md" "b/semi_annealing_2x2/annealer\343\201\253\343\201\244\343\201\204\343\201\246.md" new file mode 100644 index 0000000..777bd18 --- /dev/null +++ "b/semi_annealing_2x2/annealer\343\201\253\343\201\244\343\201\204\343\201\246.md" @@ -0,0 +1,3 @@ +# annealerについて + +2x2,4つのスピンがそれぞれ他の3つのスピンと繋がっている想定で作ってみた.構文エラーは無くしたが,果たして意図した通りに動くかは謎.もっと言えば,エネルギーが悪化するスピンの反転を認めていないので,アニーリングにもなってない代物. \ No newline at end of file -- 2.22.0