![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
ステートマシンについて、
3カウンタ回路を以下の仕様でVerilogに記述し、シミュレーションにより動作を確認せよ。
モジュール名:fsm2
入力信号名とビット数:ck(1ビット) rst(1ビット) din(1ビット)
出力信号名とビット数:dout(1ビット)
動作
・クロック入力ckの立ち上がりに同期して動作する。
・3クロック連続してdinに1が入力されると、doutに1を出力する。それ以外のときは0を出力する。
・ rstはリセット入力であり、rstが1のときは即座にdoutに0を 出力する。rstが0になって以降3クロック連続してdinに1が 入力されるまで、0を出力し続ける。
例
・ dinの入力系列011110に対して、000100を出力する。
補足
・この回路は4つの状態を有する。
という問題で、実行結果を画像のようにしたいのですが中々上手くいきません。
どうしたら画像のようになるのでしょうか?解説お願いします。
補足に画像貼れなかったため、再投稿です。
途中までのコードです。
module fsm(ck,rst,din,dout);
input ck;
input rst;
input din;
output dout;
reg [1:0] cur;
reg [1:0] nxt;
parameter S0=2'b00, S1=2'b01, S2=2'b01, S3=2'b10;
always @(rst or din or cur)begin
if(rst)
nxt<=S0;
else
case(cur)
S0:nxt<=(din==1'b1)?S1:S0;
S1:nxt<=(din==1'b1)?S2:S0;
S2:nxt<=(din==1'b1)?S3:S0;
S3:nxt<=(din==1'b1)?S3:S0;
default:
nxt<=S0;
endcase
end
always @(posedge ck)begin
cur<=nxt;
end
function dout_func;
input rst;
input din;
input [1:0] cur;
if(rst)
dout_func=1'b0;
else
case(cur)
S0:dout_func=1'b0;
S1:dout_func=1'b0;
S2:dout_func=1'b0;
S3:dout_func=(din==1'b1) ? 1'b0:1'b0;
default:
dout_func=1'bx;
endcase
endfunction
assign dout=dout_func(rst,din,cur);
endmodule
`timescale 1ps/1ps
module fsm_tp;
reg ck,rst,din;
wire dout;
parameter STEP=1000;
fsm fsm(ck,rst,din,dout);
always begin
ck=1; #(STEP/2);
ck=0; #(STEP/2);
end
initial begin
#(STEP/2) rst=1; din=0;
#(STEP/2) rst=0;
#STEP din=1;
#STEP din=1;
#STEP din=0;
#STEP din=1;
#STEP din=1;
#STEP din=1;
#STEP din=1;
#STEP din=0;
#STEP din=0;
$finish;
end
initial $monitor($stime,"ck=%b rst=%b din=%b dout=%b",ck,rst,din,dout);
endmodule
![「有限状態機械について」の質問画像](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/2/543045151_60c5fd0c66963/M.png)
No.6ベストアンサー
- 回答日時:
解決できたかどうかわからないけど、もしまだならヒントだけ。
ステートマシンで、S0からS2までの3つの状態を使っているけど、これだとうまくいかない。S0からS3までの4つの状態をすべて使うとうまくいきます。どうコードを修正するかは自分で考えてください。
以下、コード修正後、VCSで実行してみた結果。
0 : ck=1 rst=x din=x dout=x
500 : ck=0 rst=1 din=0 dout=0
1000 : ck=1 rst=0 din=0 dout=0
1500 : ck=0 rst=0 din=0 dout=0
2000 : ck=1 rst=0 din=1 dout=0
2500 : ck=0 rst=0 din=1 dout=0
3000 : ck=1 rst=0 din=1 dout=0
3500 : ck=0 rst=0 din=1 dout=0
4000 : ck=1 rst=0 din=0 dout=0
4500 : ck=0 rst=0 din=0 dout=0
5000 : ck=1 rst=0 din=1 dout=0
5500 : ck=0 rst=0 din=1 dout=0
6000 : ck=1 rst=0 din=1 dout=0
6500 : ck=0 rst=0 din=1 dout=0
7000 : ck=1 rst=0 din=1 dout=1
7500 : ck=0 rst=0 din=1 dout=1
8000 : ck=1 rst=0 din=1 dout=0
8500 : ck=0 rst=0 din=1 dout=0
9000 : ck=1 rst=0 din=0 dout=0
9500 : ck=0 rst=0 din=0 dout=0
No.5
- 回答日時:
>3000ck=1 rst=0 din=1 dout=1
これがすでにおかしい。
課題だろうから自分でデバッグすることを薦めます。まずは論理を理解して、タイミングチャートを書いてみることです。
今もうこっちは深夜なんで、明日時間があったらシミュレーションを流してみますが。
No.4
- 回答日時:
>reg [1:0] nxt_st,st;の部分がエラーが出てしまうのですが、
たぶんだけど、下のポートリストの最後にセミコロンが抜けているとかいうことありませんか。
module fsm (
input clk, rst, din,
ouptut reg dout
)
ちなみにあなたが書いたもともとの論理が正常動作しないのは、always @(rst or din or cur)の中でノンブロッキング文をつかっていることが理由です。そういう書き方をすると、dinが変化すると即座にステートレジスタが更新されて、問題として与えられている、クロックの立ち上がりに同期という前提が崩れます。
No.3
- 回答日時:
いくつか訂正。
誤
module fsm (
input clk, rst, din;
ouptut reg dout;
end
正
module fsm (
input clk, rst, din,
ouptut reg dout
)
誤
S2 : begin
if(din) dout = 0;
nxt_st = S0;
end
正
S2 : begin
if(din) dout = 1'b1;
nxt_st = S0;
end
No.2
- 回答日時:
ノンブロッキング文はそういう使い方をすると、データでフリップフロップが駆動されることになるので、やめたほうがいい。
慣れないうちは、ノンブロッキング文はクロックと合わせて使いようにしたほうがいいと思います。ステートマシンの書き方はいろいろあるけど、私はいつもこんな感じに書くことにしています。検証はしていないので、小さな間違いがあるかもしれません。自分で論理検証をやってみてください。
rst=1の時は、stが非同期リセットで即座にS0になり、その結果、always @(*)の中のデフォルトのdout = 1'b0が実行されるので、dinの値にかかわらず即座にdout=0となるはずです。
module fsm (
input clk, rst, din;
ouptut reg dout;
end
reg [1:0] nxt_st, st;
parameter S0=2'd0, S1=2'd1, S2=2'd2, S3=2'd3;
always @(posedge clk or posedge rst) begin
if(rst) st <= S0;
else st <= nxt_st;
end
always @(*) begin
nxt_st = st;
dout = 1'b0;
case(st)
S0 : if(din) nxt_st = S1;
else nxt_st = S0;
S1 : if(din) nxt_st = S2 ;
else nxt_st = S0;
S2 : begin
if(din) dout = 0;
nxt_st = S0;
end
default: begin
end
endcase
end
endmodule
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_07.png?e8efa67)
No.1
- 回答日時:
Verilog 仕様経験ないけどここおかしいんじゃない
>parameter S0=2'b00, S1=2'b01, S2=2'b01, S3=2'b10;
ステートS1、S2 の両方とも同じ 'b01
になってる
>S0:nxt<=(din==1'b1)?S1:S0;
>S1:nxt<=(din==1'b1)?S2:S0;
>S2:nxt<=(din==1'b1)?S3:S0;
>S3:nxt<=(din==1'b1)?S3:S0;
これもおかしくない?状態が変わっていかないんじゃないの
「入力1が3回連続」をカウントしたいんでしょ?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(AV機器・カメラ) 一般的なDINカーオーディオの寿命は何年くらいですか。 ナビ無しのカーオーディオで、CDや、USB端 4 2022/05/07 18:35
- 地図・道路 ポータブルカーナビゲーションで、地図を永遠に無料自動更新してくれるものはありますか。 (スマホカーナ 4 2022/12/03 09:50
- Access(アクセス) アクセス レポートを開いたときにパラメーターの自動入力がしたい 4 2022/11/30 11:21
- PHP PostgreSQLからCSV形式でエクスポートする際にカラム内の改行をとる方法 1 2023/02/22 10:05
- HTML・CSS <input>のstep属性に違反する入力をした時にエラーメッセージを表示させない事は可能か 2 2023/02/16 04:11
- BTOパソコン dz60 1 2023/06/11 15:27
- Visual Basic(VBA) このマクロの説明文を教えてほしいです。 1 2023/01/12 09:17
- その他(コンピューター・テクノロジー) ブルースクリーンエラーの発生と解決手順 2 2022/10/09 13:05
- その他(スマートフォン・携帯電話・VR) Ahamoのe-simをオンラインで購入できますか? 2 2023/03/26 20:54
- 工学 dフリップフロップで二分周器を作成してck (黄色)と出力Qの波形をオシロスコープで確認したのですが 1 2022/11/30 22:19
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クランプ回路
-
400V 3相4線式について...
-
パルスとレベルについて
-
オペアンプ/反転増幅器/頭打ち
-
近接スイッチの2線式と3線式...
-
EVT(GPT)の電圧比について
-
NPNとPNPの違いについて
-
電気設備で使われるGCの意味...
-
電気回路のπ型回路の2端子対回...
-
60Hz誘導電動機を関東の50H...
-
同一電圧値、異なる電源供給源...
-
利得と増幅率
-
直流負荷線ってなんですかね、 ...
-
オペアンプ、コンパレータ等を...
-
電気回路について
-
ベース変調方式におけるLC共振
-
8ビット電文出力とはどんな信号?
-
流量計のパルス出力について
-
電気回路でこの問題でIAとI1が...
-
[LT Spice] オペアンプのシミュ...
おすすめ情報
回答ありがとうございます。
reg [1:0] nxt_st,st;
の部分がエラーが出てしまうのですが、何か間違っているのでしょうか?
ありがとうございました。
上手くいきました。
ちなみにこのときの状態遷移図はどのようになるのでしょうか?
何度もすみません。
実行結果の
3000ck=1 rst=0 din=1 dout=1
3500ck=0 rst=0 din=1 dout=1
6000ck=1 rst=0 din=1 dout=1
6500ck=0 rst=0 din=1 dout=1
の部分に1が出てしまいます。
どうすれば7000と7500に1を出力できますか?