5.3 各種カウンタ 平木
5.3.1 バイナリ・カウンタ Verilog HDL記述 バイナリ・カウンタとは、クロックが立ち上がると1ずつカウントしていく。 5.3.1 バイナリ・カウンタ Verilog HDL記述 バイナリ・カウンタとは、クロックが立ち上がると1ずつカウントしていく。 モジュールの作成 入出力信号の設定 リセット信号が1ならば0 リセット信号が0ならば1を足す シミュレーション結果
5.3.2 アップ/ダウン・カウンタ Verilog HDL記述 アップ/ダウンカウンタとは、バイナリカウンタを拡張したもの。 5.3.2 アップ/ダウン・カウンタ Verilog HDL記述 アップ/ダウンカウンタとは、バイナリカウンタを拡張したもの。 down信号が ‘1’:カウント・ダウン 0→15→14・・・1→0・ ‘0’:カウント・アップ 0→1→2・・・15→0・・ シミュレーション結果
5.3.3 グレイ・コード・カウンタ 2 進数は 0, 1, 10, 11 と始まり、グレイコードは、0, 1, 11, 10 と始まるようにしたコード。 2進数 グレイコード 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1101 1100 1110 1111
5.3.3 グレイ・コード・カウンタ Verilog HDL記述 グレイ・コード・カウンタとは、常に出力が1bitだけ変化するカウンタ。 5.3.3 グレイ・コード・カウンタ Verilog HDL記述 グレイ・コード・カウンタとは、常に出力が1bitだけ変化するカウンタ。 グレイコード生成入力 現在カウンタ値 次カウンタ値 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000 グレイ・コード生成部 真理値表
5.3.3 グレイ・コード・カウンタ シミュレーション結果 ひげが発生しない
5.3.4 手抜きグレイ・コード・カウンタ Verilog HDL記述 バイナリ・コード バイナリ・カウンタ グレイ・コード 5.3.4 手抜きグレイ・コード・カウンタ Verilog HDL記述 バイナリ・コード バイナリ・カウンタ グレイ・コード バイナリ・コード(4ビット2進数)からグレイ・コードへの変換は隣り合ったビットのEX-ORで生成することができる。そして、このコード変換をバイナリ・カウンタの出力に接続する。
計算機工学特論A テキスト内容 5.3.5 ~ 5.3.8 山越研 河合 智功
ジョンソン・カウンタ 1クロックごとに順次「1」の状態のビットが増加していき、全ビットが「1」になった後、順次「1」の状態が減っていく動作を行う計数カウンタ。
ジョンソン・カウンタ 0000 1111 00001 11110 13行目と14行目を反転した場合 設定ビット数より上位なので無視 各ビットの状態が「0000」の場合 各ビットの状態が「1111」の場合 13行目と14行目を反転した場合
ジョンソン・カウンタ シミュレーション結果
ループ対策ジョンソン・カウンタ ジョンソン・カウンタ 不正ループ対策あり ジョンソン・カウンタ 不正ループ対策
q[0] <= ~q[3] | ( q[0] & ~q[2] ) ループ対策ジョンソン・カウンタ 1011 ループ対策前 1001 一度不正ループになると正常に戻すのがかなり困難 10010 10110 q[0] <= ~q[3] | ( q[0] & ~q[2] ) X= ( q[0] & ~q[2] ) q[0] <= ~q[3] | X AND OR 1011 ループ対策後 1001 不正ループから本来の動作に復帰している 10011 10111
リング・カウンタ クロック1周期で出力の1本のみが常に「1」になるカウンタ
always文に入る前の「q」と「ff」の各ビットの状態 リング・カウンタ always文に入る前の「q」と「ff」の各ビットの状態 q 0000 0001 0010 ff 000 000 001 ff 000 001 010 q[0] 1 q 0001 0010 0100 NOR
リング・カウンタ シミュレーション結果
ディバイダ(分周回路) ディバイダはある周波数のクロック信号から、それよりも低い周波数のクロック信号を作るときに使用する。 q[0]はクロックに対して1/2の周波数になっている。q[1]はクロックに対して1/4の周波数になっている。
ディバイダ(分周回路)
ディバイダ(分周回路) Wire型変数「q2、q1、q0」を使用しなくても同じ動作はシミュレーションできる
22. シフト・レジスタ と レジスタ・ファイル 12月12日 山越研究室 増山 知東
レジスタとは 8bit、16bit、32bit ・・・ 等のデータを一時的に記憶するもの。 シフト・レジスタとは レジスタとは 8bit、16bit、32bit ・・・ 等のデータを一時的に記憶するもの。 シフト・レジスタはその記憶しているデータの桁を左右にシフトできるものを指す。 【シフト・レジスタの分類】 【シフト・レジスタのイメージ】 シリアル入力-シリアル出力 パラレル入力-シリアル出力 シリアル入力-パラレル出力 パラレル入力-パラレル出力 ・
シリアル入力-パラレル出力 記述 シミュレーション結果 // 4bit シリアル・パラレル変換 module Seri_Par(ck,res,en,si,q); input ck,res,en,si; output [3:0] q; reg [3:0] q; always@(posedge ck) begin クロックの立ち上がりごとに実行 if (res) q <= 4’h0; 4bit 16進数表現で 0 が代入 else if (en) begin q <= q << 1; 1bit左シフト→q[0]には 0 が代入 q[0] <= si; q[0]に si の値が代入 end endmodule シミュレーション結果
シリアル入力-パラレル出力 NG編その1 記述 シミュレーション結果 0が常に入力された状態 // 4bit シリアル・パラレル変換 NG編1 module Seri_Par(ck,res,en,si,q); input ck,res,en,si; output [3:0] q; reg [3:0] q; always@(posedge ck) begin クロックの立ち上がりごとに実行 if (res) q <= 4’h0; 4bit 16進数表現で 0 が代入 else if (en) begin q[0] <= si; q[0]に si の値が代入 q <= q << 1; 1bit左シフト→q[0]には 0 が代入 end endmodule シミュレーション結果 0が常に入力された状態
シリアル入力-パラレル出力 NG編その2 記述 シミュレーション結果 最下位bitを飛び越えてしまっている // 4bit シリアル・パラレル変換 NG編2 module Seri_Par(ck,res,en,si,q); input ck,res,en,si; output [3:0] q; reg [3:0] q; always@(posedge ck) begin クロックの立ち上がりごとに実行 if (res) q = 4’h0; 4bit 16進数表現で 0 が代入 else if (en) begin q[0] = si; q[0]に si の値が代入 q = q << 1; 1bit左シフト→q[0]には 0 が代入 end endmodule シミュレーション結果 最下位bitを飛び越えてしまっている
シリアル入力-パラレル出力 シフト演算を用いない方法 シリアル入力-パラレル出力 シフト演算を用いない方法 記述 シミュレーション結果 // 4bit シリアル・パラレル変換 シフト演算を用いない方法 module Seri_Par(ck,res,en,si,q); input ck,res,en,si; output [3:0] q; reg [3:0] q; always@(posedge ck) begin クロックの立ち上がりごとに実行 if (res) q <= 4’h0; 4bit 16進数表現で 0 が代入 else if (en) q <= {q , si}; 4bit + 1bit を 4bit に代入 end endmodule 例) 5bit の信号を 4bit に代入 結果、最上位bitが欠落
パラレル入力-シリアル出力 記述 シミュレーション結果 出力 so はレジスタ ps の3bit そのもの module Par_Seri(ck,en,ld,pi,so); input ck,en,ld; input [3:0] pi; output so; reg [3:0] ps; always@(posedge ck) begin クロックの立ち上がりごとに実行 if (ld) ps <= pi; else if (en) ps <= ps << 1; 1bit左シフト→ps[0]には 0 が代入 end assign so = ps[3]; endmodule シミュレーション結果 出力 so はレジスタ ps の3bit そのもの
レジスタ・ファイル ・・・ ビット幅を持ったレジスタの集合体 レジスタ・ファイル ・・・ ビット幅を持ったレジスタの集合体 記述 シミュレーション結果 // 8bit × 4 レジスタ・ファイル module regfile(ck,we,din,inaddr,dout,outaddr); input ck,we; input [7:0] din; input [1:0] inaddr, outaddr; 00, 01, 10,11で レジスタの指定可 output [7:0] dout; reg [7:0] file [0:3]; always@(posedge ck) クロックの立ち上がりごとに実行 if (we) file (inaddr) <= din; inaddr で指定し、din に代入 assign dout = file[outaddr]; outaddr で指定し、dout に代入 endmodule inaddr ・・・ 00 outaddr ・・・ 00
レジスタ・ファイル ・・・ ビット幅を持ったレジスタの集合体 レジスタ・ファイル ・・・ ビット幅を持ったレジスタの集合体 シミュレーション結果A シミュレーション結果B シミュレーション結果C inaddr ・・・ 00 outaddr ・・・ 00 inaddr ・・・ 00 outaddr ・・・ 01 inaddr ・・・ 00 & 01 outaddr ・・・ 00 & 01
計算機工学特論A Vrilog-HDL 23 ステートマシン 山越研究室 修士1年 赤津 実幸
5.6.1 ステートマシンの目的 回路システム データパス系 演算などのデータ処理が中心 制御系 データパス系に対する制御信号を作成 (リセット、カウンタ、FFのイネーブル信号など) 制御信号は回路仕様に応じて順次ON/OFFされる ステートマシンとは 制御信号を作り出すための順序制御回路
ステートマシンの具体例 デジタルウォッチ 表示ブロック 制御ブロック カウントブロック ステートマシンの具体例 デジタルウォッチ 使用例としてデジタルウォッチ内でどのようにステートマシンが利用されるか検証する。 SW1: 設定 時刻を変更する SW2: モード切り替え 通常モード⇔時刻修正モード SW3: けた選択 秒修正⇒時修正⇒分修正 デジタルウォッチのブロック図 表示 表示ブロック 制御ブロック カウントブロック sysreset ck SW1~SW3 本例のデジタルウォッチは計時するだけではなく、時刻修正も可能 「通常の状態」と「修正中の状態」を表す「ステート(状態)」の概念が必要
具体的なデジタルウォッチのステート(状態) ストップウォッチの4つの状態 ・通常状態 ・時修正状態 ・分修正状態 ・秒修正状態 デジタルウォッチの状態遷移図 各修正モード時のSW1(設定)の動作 ステートマシン 状態遷移図を回路に置き換えたもの
5.6.2 ステートマシンの構成法 ワン・ホット方式 デコード方式 ワン・ホット方式の利点 ・使用するFFの量が多い ・動作スピードは速い 5.6.2 ステートマシンの構成法 ワン・ホット方式 デコード方式 ワン・ホット方式の利点 ・使用するFFの量が多い ・動作スピードは速い ・用途によっては、複数の状態が同時にアクティブにならないためのフェイルセーフ 的な回路が必要 デコード方式の利点 ・使用するFFの量が少ない ・状態数が多いと状態デコーダ部分の回路規模が大きくなり、動作速度が遅くなる。 ・HDL記述が簡潔で分かりやすい
デコード方式ステートマシンの記述例(リスト5.1) ステートマシン2方式の共通項目 ステート名: NORMAL(通常)、SEC(秒修正)、HOUR(時修正)、MIN(分修正) スイッチ入力: SW1、SW2、SW3(いづれもクロック一周分のパルスとする) 出力: SW1が押されたときの動作 sec_reset(秒リセット)、hour_inc(+1時)、min_inc(+1分) モードON/OFFの表示 sec_onoff、hour_onoff、min_onoff
リスト5.1の説明1 curは現在の状態 nxtはアクションによる状態遷移を表す reg [1:0] cur; //ステートレジスタ reg [1:0] nxt; //ステート生成回路 (組み合わせ回路) curは現在の状態 nxtはアクションによる状態遷移を表す parameter NORMAL = 2’b00, SEC = 2’b01, MIN = 2’b10, HOUR = 2’b11 2ビットの状態変数curやnxtにステート情報を伝えるために定義する。 後述のステートデコーダでnxt<=NORMALなどの形で代入を行う。 always@( posedge ck or posedge sysreset ) begin if ( sysreset ) cur <= NORMAL; else cur <= nxt; end sysresetは初期化を行っており、強制的に通常モードに戻します。 sysresetが押されていない場合は状態遷移図に従って動作します。
リスト5.1の説明2 ステート生成回路(ステートデコーダ) クロックとは無関係に cur(状態を表すレジスタ) SW1(設定) の変更に合わせて動作する。 always @( cur or SW1 or SW2 or SW3 ) begin case( cur ) NORMAL: if (SW2) nxt <= SEC; else nxt <= NORMAL; SEC:~~~~ HOUR:~~~~ MIN:~~~~ default: nxt <= 2’bxx; endcase end SW2の入力があるとき 状態NORMALの場合 nxt <= SECで秒修正モードに移行 状態SEC,HOUR,MINの場合 nxt <= NORMALで通常モード に移行 SW2の入力がないとき nxt <=今の状態を代入して状態の変更をしない
リスト5.1の説明3 追加 ※複雑な制御を行う場合下記ような記述をすることがあるそうです。 カウント・ブロックに送られる制御信号 assign sec_reset = ( cur == SEC ) & SW1; assign min_inc = ( cur == MIN ) & SW1; assign hour_inc = ( cur == HOUR ) & SW1; どの状態のときにSW1が押されたか、という情報をカウント・ブロックに送ります 表示ブロックに送られる制御信号 assign sec_onoff = ( cur == SEC ); assign min_onoff = ( cur == MIN ); assign hour_onoff = ( cur == HOUR ); 修正モード時に修正部分を点滅させるために現在どの修正モードであるかという情報を表示ブロックに送ります 追加 ※複雑な制御を行う場合下記ような記述をすることがあるそうです。 assign xx_enable = ( ( cur == xxx) | (cur == yyy ) | ( cur == zzz) | ・・・) & yy_enable おそらく今回のステートマシンには関係ない。
シミュレーションによる検証1 クロック周期100us 10000Hz モードの変更例 NORMAL(通常) SEC(秒修正) SW3 ON SW2 ON NORMAL(通常) SEC(秒修正) HOUR(時修正) SW2(通常⇔修正モード)で秒修正に移り SW3(秒⇒時⇒分)により秒修正から時修正に移っていることが分かる
シミュレーションによる検証2 SW1動作例 NORMAL(通常) SEC(秒修正) SEC(秒修正)リセット NORMAL(通常) SEC(秒修正) 秒修正状態のときにSW1(設定)を押したときに秒修正の秒リセットがONになっていることが分かる