140 likes | 242 Views
Turing Machine を作る. 教養学部1年理科1類 水口康彦. 材料. XSP-006-200 評価ボード 7SEG LED 6つ スイッチ 4つ LED 4つ ブザー1つ シリアルポート1つ 時間 7,8コマほど. 動機. チューリングマシンシミュレーターはたくさんあるが、ハードウェアでの実装例は少ない 少し貧困な評価ボードの IO を生かす. http://member.nifty.ne.jp/mindstorms/gallery/k025.html. 実装. 8状態*16シンボル テープは4ビット*128文字(輪)
E N D
TuringMachineを作る 教養学部1年理科1類 水口康彦
材料 XSP-006-200 評価ボード • 7SEGLED 6つ • スイッチ 4つ • LED 4つ • ブザー1つ • シリアルポート1つ 時間 7,8コマほど
動機 • チューリングマシンシミュレーターはたくさんあるが、ハードウェアでの実装例は少ない • 少し貧困な評価ボードのIOを生かす http://member.nifty.ne.jp/mindstorms/gallery/k025.html
実装 • 8状態*16シンボル • テープは4ビット*128文字(輪) • テープへのインプットにRS232Cを使う TM 計算実行 文字書き換え
できたもの • パリティーチェッカー 入力された2進数のパリティーを計算 • ()検査器 入力された()の対応があっているか調べる • 2進数 to 10進数 変換器 入力された2進数を10進数に変換
()検査器 • 3状態4つのシンボル ( ) _ E を使って実装 L R L START
実行 • TeraTermからテープに初期テープデータを入力(スイッチでもできるけど大変) • 計算実行ボタンが押されている間TMは内部の5つ組み回路にそって計算を実行 • E((()()))())(())()()E → “B”と印字 • E()()()()E → “A”と印字
[Q0,"0"]-> [Q0,"0"] :: R [Q0,"1"]-> [Q0,"1"] :: R [Q0,"B"]-> [Q0,"B"] :: R [Q0,"E"]-> [Q1,"E"] :: L [Q0,"A"]-> [Q4,"A"] :: R [Q1,"0"]-> [Q1,"0"] :: L [Q1,"1"]-> [Q2,"A"] :: L [Q1,"B"]-> [QH,"B"] :: L [Q2,"0"]-> [Q2,"0"] :: L [Q2,"1"]-> [Q2,"1"] :: L [Q2,"B"]-> [Q3,"B"] :: L [Q3,"_"]-> [Q0,"1"] :: R [Q3,"0"]-> [Q0,"1"] :: R [Q3,"1"]-> [Q0,"2"] :: R [Q3,"2"]-> [Q0,"3"] :: R [Q3,"3"]-> [Q0,"4"] :: R [Q3,"4"]-> [Q0,"5"] :: R [Q3,"5"]-> [Q0,"6"] :: R [Q3,"6"]-> [Q0,"7"] :: R [Q3,"7"]-> [Q0,"8"] :: R [Q3,"8"]-> [Q0,"9"] :: R [Q3,"9"]-> [Q3,"0"] :: L [Q4,"0"]-> [Q4,"0"] :: R [Q4,"1"]-> [Q4,"1"] :: R [Q4,"E"]-> [Q5,"E"] :: L [Q5,"0"]-> [Q5,"1"] :: L [Q5,"1"]-> [Q5,"0"] :: L [Q5,"A"]-> [Q0,"0"] :: L 2進数 to 10進数 変換
細々苦労した点 • テープへの書き込みを随時行っていたらSLICEsをすぐ使い切ってしまってた → テープへの書き込みは毎clk最後に一括 → 629 out of 2352 26% • 状態遷移をif-else ifで長々書いていたら、コンパイルが遅すぎてPCが止まってしまった → switch caseつかったら大丈夫になった
tape parameter ssize=4; parameter wsize=128; reg[6:0] position; reg[ssize-1:0] tapebit[0:wsize-1]; wire[ssize-1:0] data; reg[ssize-1:0] wdata; reg wbit; reg lbit; reg rbit; assign data=tapebit[position]; • テープは配列 • リング構造にして有効に利用 • テープを書き換えるための各種フラグ wdata,wbit,lbit,rbit
Updateで、テープをフラグにそって更新 update always@ (posedge clk) begin if(実行ボタンがおされていれば) 分周してすこしまってから step; end その他のキー処理 RS232Cの処理 update; end
計算実行 状態遷移 task step; begin /* parity checker */ case({state,data}) {3'd0,4'd0}: newstate(0,3,1); {3'd0,4'd1}: newstate(1,3,1); {3'd1,4'd0}: newstate(0,3,1); {3'd1,4'd1}: newstate(0,3,1); {3'd0,4'd2}: newstate(2,4,1); {3'd1,4'd2}: newstate(0,5,1); endcase end endtask parameter qsize=3; reg[qsize-1:0] state; task newstate; input[qsize-1:0] s; input[ssize-1:0] r; input m; // 1: right 0: left begin write(r); state=s; if(m==1) shiftr; else if(m==0) shiftl; end endtask
まとめ • VerilogやFPGAの中身を理解していないのが、SLICEを消費しすぎる原因 ハードウェア記述言語は難しい • Universal Turing Machineを作る予定だったのに、時間がなくて到達できなかった。が、おそらくできる。(ただしテープの長さには限りがある) • FPGAはチューリングコンプリートだ!