論理設計実習 第3回

論理設計実習
第3回
Verilog-HDL入門(1)
開発ツールを使ってみよう
井口幸洋
2015/9/30
1
識別子
• 識別子
– 信号
– 定数
– モジュール(機能別にまとめたブロック,部品)の
名前
– パラーメータに付ける名前
2015/9/30
2
識別子の付け方
• 使用できる文字
– アルファベットの大文字と小文字
– 数字
– アンダースコア( _ )
– ダラー ( $ )
– 先頭文字はアルファベットかアンダースコア
– 予約語は使えない
2015/9/30
3
識別子の例
• 良い例
– a, clock, clock_, reset_N
• 不正な例
– 4to1MUX ← 数字が先頭
– reset* ← 使えない文字がある
– event ← 予約語
• アルファベットの大文字と小文字は区別されるが,シミュレー
タなどによっては区別されないものもあるし,わかりにくいの
で大文字と小文字で同じものは付けるべきではない.
– 例: clock と CLOCK
• 先頭に_や$がつく識別子は特別な用途に使うなどの場合が
あるので, この講義では先頭はアルファベットにすることにす
ることを強く勧める.
• 名前の付け方は,良い本のまねをすること.
2015/9/30
4
Verilog-HDLで取り扱う論理値
• 0, 1, x, z
– 0: 真理値0. False.
– 1: 真理値1. True.
– x または X: 不定, unknown. 例えば, D-FFは電
源をONしたとき,出力Qは0か1のどちらになる
かはわからない.
– z または Z: ハイインピーダンス.高い抵抗で結
ばれている,つまり,どことも接続されていない状
態. Hi-Z, Hi-zとテキストでは書かれることもある.
2015/9/30
5
ハイインピーダンス状態とはどんな状態か?
NOT回路の復習
Vdd = 3.3[V]
Vdd = 3.3[V]
off
1
off
0
on
Vss = 0 [V]
0
on
Vss = 0 [V]
Vss = 0 [V]
Vdd = 3.3[V]
Vdd = 3.3[V]
on
on
1
0
off
Vss = 0 [V]
2015/9/30
Vdd = 3.3[V]
1
off
Vss = 0 [V]
6
ハイインピーダンス状態とはどんな状態か?
NOT回路にトランジスタ・スイッチを追加する
Vdd = 3.3[V]
0
on
Vdd = 3.3[V]
1
=
1
on
Vss = 0 [V]
Vdd = 3.3[V]
1
off
0
off
=
0
Vss = 0 [V]
Vss = 0 [V]
出力側から見るとどこにも接続されて
いないことがわかる
2015/9/30
7
さまざまなスリーステートバッファ
OE
OE
in
out
OE in out
0
0
z
0
1
z
1
0
1
1
2015/9/30
OE in out
0
x
z
1
1
0
0
1
1
in
out
OE in out
0 0 z
OE in out
0
x
z
0
1
z
1
1
0
0
1
0
0
0
1
1
1
1
1
1
8
さまざまなスリーステートバッファ
OE
OE
in
out
OE in out
0
0
1
0
1
0
1
0
1
1
2015/9/30
OE in out
0
0
1
z
0
1
z
1
x
in
out
OE in out
0 0 0
OE in out
0
0
0
0
1
1
0
1
0
z
0
1
1
z
1
1
z
1
x
z
9
本日の課題
• ISE 8.2i クイック・スタート・チュートリアルに
従ってISEの使い方を学ぶ (pp. 1 - 21)
• 入力しシミュレーションする対象回路
– アップ/ダウン・カウンタ(Up/Down Counter)
– 入力:
• CLOCK信号
• DIRECTION (1ならアップカウンタ,0ならダウンカウ
ンタ)
– 出力:
• COUNT_OUT (4-bitのカウンタ出力)
2015/9/30
10
アップ/ダウン・カウンタのソースリスト
module counter(CLOCK, DIRECTION, COUNT_OUT);
input CLOCK;
input DIRECTION;
output [3:0] COUNT_OUT;
reg [3:0] count_int = 0;
always @(posedge CLOCK)
if (DIRECTION)
count_int <= count_int + 1;
else
count_int <= count_int – 1;
assign COUNT_OUT = count_int;
endmodule
2015/9/30
11
アップ/ダウン・カウンタの解明 (1)
module counter(CLOCK, DIRECTION, COUNT_OUT);
input CLOCK;
セミコロン ; を忘れずに!
input DIRECTION;
モジュールの名前は, counterの
output [3:0] COUNT_OUT;
ようにわかりやすい識別子にする
reg [3:0] count_int = 0;
moduleとendmoduleで囲む
always @(posedge CLOCK)
if (DIRECTION)
count_int <= count_int + 1;
else
count_int <= count_int – 1;
assign COUNT_OUT = count_int;
endmodule
2015/9/30
12
アップ/ダウン・カウンタの解明 (2)
module counter(CLOCK, DIRECTION, COUNT_OUT);
input CLOCK;
CLOCKとDIRECTIONは1ビット幅の入力
input DIRECTION;
COUNT_OUTは4ビット幅の出力
output [3:0] COUNT_OUT;
count_intは4ビット幅のレジスタ.
初期値は0にする.
reg [3:0] count_int = 0;
always @(posedge CLOCK)
if (DIRECTION)
count_int <= count_int + 1;
else
count_int <= count_int – 1;
assign COUNT_OUT = count_int;
endmodule
2015/9/30
CLOCKの立ち上が
りが起きるごとに
この文の所を実行
内部レジスタ count_int を
外部出力 COUNT_OUT
に接続
13
クロック信号とは何か?
• 順序回路を一つの信号の合図でいっせいに
動かすための信号(このような信号を同期信
号という)
• デジタル回路では 0 → 1 → 0 → 1 と交互に
0と1とが交替する信号を使う
t
2015/9/30
14
クロック信号の立ち上がりと立下り
• 同期をとるタイミングはいつ?
– 立ち上がり(positive edge): 0から1に変化する瞬間
• 例: always @(posedge CLOCK)
– 立ち下がり(negative edge): 1から0に変化する瞬間
• 例: always @(negedge CLOCK)
t
2015/9/30
15
アップ/ダウン・カウンタの解明 (3)
always @(posedge CLOCK)
if (DIRECTION)
count_int <= count_int + 1;
else
count_int <= count_int – 1;
CLOCKの立ち上がり信号がくるたびに
もし DIRECTION が1なら
内部レジスタ count_int に 1を足す
そうでないならば(つまり0なら)
内部レジスタ count_int から1をひく
2015/9/30
16
アップ/ダウン・カウンタの構造
4
count_int
DQ
C
CLOCK
4
-
1
DQ
C
4
DQ
C
4
4
4
+
4
D0
Y
D1
S
COUNT_OUT
1
DQ
C
DIRECTION
注意:リセット回路は省略してあります
他の構成法も考えられます.
皆さんでもっとよい回路がないか考えてみるのも良いでしょう.
2015/9/30
17