Commit b46a960d authored by yuki.yahagi's avatar yuki.yahagi

2x2のアニーリングマシンっぽいものを作ってみた.

parent 36b9c537
...@@ -17,4 +17,11 @@ kenbaiki_TB.v : *kenbaiki.vのテストベンチ* ...@@ -17,4 +17,11 @@ kenbaiki_TB.v : *kenbaiki.vのテストベンチ*
input clk, reset_N; //クロック信号とリセット信号の入力 input clk, reset_N; //クロック信号とリセット信号の入力
このように,何を入力で与え,それぞれのビット幅がいくつになるのか,それぞれのビットは何を表すのかをきちんと決めることが設計で重要になってくる. このように,何を入力で与え,それぞれのビット幅がいくつになるのか,それぞれのビットは何を表すのかをきちんと決めることが設計で重要になってくる.
\ No newline at end of file
## ブロッキング代入とノンブロッキング代入について
verilogだと,代入文が "=" と "<=" の二種類ある.
"="がブロッキング代入で,ファイルの上から順番に代入をしていく逐次処理の構文,"<="がノンブロッキング代入で,代入したい値が変化したら即座に代入される.
assignでは "=" を,always文中では "<=" を使った方がいいのだが,この券売機の例では全部 "=" になっているので注意.
\ No newline at end of file
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
# annealerについて
2x2,4つのスピンがそれぞれ他の3つのスピンと繋がっている想定で作ってみた.構文エラーは無くしたが,果たして意図した通りに動くかは謎.もっと言えば,エネルギーが悪化するスピンの反転を認めていないので,アニーリングにもなってない代物.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment