From 36b9c53745f591654428d794948ad14cac7613be Mon Sep 17 00:00:00 2001 From: "yuki.yahagi" Date: Wed, 30 May 2018 13:50:20 +0900 Subject: [PATCH] =?UTF-8?q?=E5=88=B8=E5=A3=B2=E6=A9=9F=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E8=A8=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kenbaiki/kenbaiki.v | 102 ++++++++++++++++++ kenbaiki/kenbaiki_TB.v | 75 +++++++++++++ ...53\343\201\244\343\201\204\343\201\246.md" | 20 ++++ 3 files changed, 197 insertions(+) create mode 100644 kenbaiki/kenbaiki.v create mode 100644 kenbaiki/kenbaiki_TB.v create mode 100644 "kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" diff --git a/kenbaiki/kenbaiki.v b/kenbaiki/kenbaiki.v new file mode 100644 index 0000000..f99d2ea --- /dev/null +++ b/kenbaiki/kenbaiki.v @@ -0,0 +1,102 @@ +// お金は50円と100円,券は50円券と100円券. +// in, payback, outは,上位ビットで有(1)無(0), +// 下位ビットで50円(0)か100円(1)を判断. +// 払い戻しは余剰にお金が入った時のみの鬼畜仕様. +// 券発行よりもお金投入を優先する. + +module kenbaiki(in, ticket, clk, reset_N, payback, out); + input [1:0] in; //上位ビットがお金投入,下位ビットがお金の種類 + input ticket, clk, reset_N; //順にチケット発行,クロック,リセット信号(0入力でリセット) + output [1:0] payback; //上位ビットが払い戻し有り無し,下位ビットがお金の種類 + output [1:0] out; //上位ビットがお金投入,下位ビットがお金の種類 + + reg s1,s2,s3; //現在のステートを記憶 + //s1は料金0円の初期状態,s2は50円投入,s3は100円投入 + reg [1:0] rpay, rout; //wireにはassign文でしか値を代入できない + //regにはalways構文中でしか値を代入できない + //outputはwireなので,always構文で動作するステートマシンの出力をする時は, + //always構文中で使うregを経由してからassign文で出力する. + + assign payback = rpay; + assign out = rout; + + always @(posedge clk or negedge reset_N) begin + if(!reset_N) begin //reset_N = 0でリセットをかける + {s1, s2, s3} = 3'b100; //初期状態にする,{}はverilogで複数の変数をまとめて扱うことに使う + rpay = 2'b00; + rout = 2'b00; + end else begin + if (s1) begin //投入金額0円 + case (in) //金額の投入を判断 + 8'b10: {s1, s2, s3} = 3'b010; //50円投入 + 8'b11: {s1, s2, s3} = 3'b001; //100円投入 + default: {s1, s2, s3} = 3'b100; //それ以外 + endcase + rpay = 2'b00; + rout = 2'b00; + end else if (s2) begin //投入金額50円 + if (in[1]) begin //お金が投入されていた場合 + case (in) + 8'b10: //50円投入 + begin + {s1, s2, s3} = 3'b001; + rpay = 2'b00; + end + 8'b11: //100円投入 + begin + {s1, s2, s3} = 3'b001; + rpay = 2'b10; //50円払い戻し + end + default: //それ以外 + begin + {s1, s2, s3} = 3'b010; + rpay = 2'b00; + end + endcase + rout = 2'b00; + end else if (ticket) begin //発券信号有りのとき + {s1, s2, s3} = 3'b100; //初期状態に戻して + rpay = 2'b00; + rout = 2'b10; // 50円券発行 + end else begin //何もされていなかったとき + {s1, s2, s3} = 3'b010; + rpay = 2'b00; + rout = 2'b00; + end + end else if (s3) begin //投入金額100円 + if (in[1]) begin //お金が投入されていた場合 + case (in) + 8'b10: //50円投入 + begin + {s1, s2, s3} = 3'b001; + rpay = 2'b10; //50円払い戻し + end + 8'b11: //100円投入 + begin + {s1, s2, s3} = 3'b001; + rpay = 2'b11; //100円払い戻し + end + default: //それ以外 + begin + {s1, s2, s3} = 3'b001; + rpay = 2'b00; + end + endcase + rout = 2'b00; + end else if (ticket) begin //発券信号有りの時 + {s1, s2, s3} = 3'b100; //初期状態に戻して + rpay = 2'b00; + rout = 2'b11; // 100円券発行 + end else begin //何もされていなかったとき + {s1, s2, s3} = 3'b001; + rpay = 2'b00; + rout = 2'b00; + end + end else begin //ステートがおかしくなっていた時 + {s1, s2, s3} = 3'b100; //初期状態にする + rpay = 2'b00; + rout = 2'b00; + end + end + end +endmodule diff --git a/kenbaiki/kenbaiki_TB.v b/kenbaiki/kenbaiki_TB.v new file mode 100644 index 0000000..96bfc1f --- /dev/null +++ b/kenbaiki/kenbaiki_TB.v @@ -0,0 +1,75 @@ +// kenbaiki_TB.v +`timescale 1ns/1fs + +module kenbaiki_TB; + reg ticket, clk, reset_N; // input + reg [1:0] in; // input + wire [1:0] payback, out; // output + + parameter CLOCK = 2.0; // クロック周期(ns) + + kenbaiki kenbaiki(in, ticket, clk, reset_N, payback, out); // テストにかける回路の準備 + + initial clk = 1; // クロックの準備 + always #(CLOCK/2) // クロックを作っている + clk <= ~clk; + + initial // おまじない + begin + $dumpfile("rtl.dump"); // 出力されるダンプファイル(これを元に波形が見れます) + $dumpvars(0,kenbaiki_TB); + end + + initial // おまじないらしいよ + begin + in <= 2'b00; + ticket <= 1'b0; //初期化 + reset_N <= 1'b0; //resetは0入力でかかる + repeat(2) @(negedge clk); // 信号の変化はクロック立ち上がりでやってはよくない + // そのため2つクロックが立ち下がるまで待つ + reset_N <= 1'b1; //リセットを解除 + + //50円->待機->50円->発券 + #(CLOCK) // 1クロック待機 + in <= 2'b10; + #(CLOCK) // 1クロック待機 + in <= 2'b00; + #(CLOCK) // 1クロック待機 + in <= 2'b10; + #(CLOCK) + in <= 2'b00; + ticket <= 1'b1; + + //50円->発券 + #(CLOCK) // 1クロック待機 + in <= 2'b10; + ticket <= 1'b0; + #(CLOCK) + in <= 2'b00; + ticket <= 1'b1; + + //100円->50円->発券 + #(CLOCK) // 1クロック待機 + in <= 2'b11; + ticket <= 1'b0; + #(CLOCK) // 1クロック待機 + in <= 2'b10; + #(CLOCK) + in <= 2'b00; + ticket <= 1'b1; + + //50円->100円->発券 + #(CLOCK) // 1クロック待機 + in <= 2'b10; + ticket <= 1'b0; + #(CLOCK) // 1クロック待機 + in <= 2'b11; + #(CLOCK) + in <= 2'b00; + ticket <= 1'b1; + + #(CLOCK*6) //6クロック待機 + + $finish; //シミュレーション終了 + end +endmodule 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" new file mode 100644 index 0000000..b77d4a0 --- /dev/null +++ "b/kenbaiki/kenbaiki\343\201\253\343\201\244\343\201\204\343\201\246.md" @@ -0,0 +1,20 @@ +# kenbaikiについて + +## ファイル一覧 +kenbaiki.v : *券売機のRTLファイル* + +kenbaiki_TB.v : *kenbaiki.vのテストベンチ* + +## 設計について +50円券と100円券を売り出す券売機を考える. +お金は50円玉と100円玉だけを受け付け,投入された金額に応じた券を出す(100円分入ってたら50円券は買えず,必ず100円券が出てくる). +券売機は箱に,お金の投入口,発券ボタン1つ,発券口,余剰なお金の払い戻し口がついている構成.以下,入出力の詳細. + + input [1:0] in; //お金の入力(2ビット),上位ビットがお金投入の有無,下位ビットがお金の種類 + input ticket; //発券ボタンの入力,投入されている金額に応じた券を発券 + output [1:0] payback; //余剰な投入金額の払い戻し出力,上位ビットが払い戻しの有無,下位ビットががお金の種類 + output [1:0] out; //発券の出力,上位ビットが発券の有無,下位ビットが券の種類 + + input clk, reset_N; //クロック信号とリセット信号の入力 + +このように,何を入力で与え,それぞれのビット幅がいくつになるのか,それぞれのビットは何を表すのかをきちんと決めることが設計で重要になってくる. \ No newline at end of file -- 2.22.0