論理設計実習 第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
© Copyright 2025 ExpyDoc