計算機工学特論A 第4回 論理合成 山越研究室 増山 知東 2007年11月7日
論理合成とは? HDL言語で書かれたソースファイルを ゲート回路のような“素子”に変換し それらを組み合わせ、機能を向上させること。 ゲート回路のような“素子”に変換し それらを組み合わせ、機能を向上させること。 但し、論理合成に不向きな言語仕様もある。 module 1 module 3 module 2
具体的な方法 ソースファイルである .v ファイルから シンボルファイル(.bsf ファイル)を作成する File → Create/Update → Create Symbol Files for Current File を選択すると .v ファイルで作成した プログラムのシンボルファイルを作成できる。
具体的な方法 作成したシンボルファイルを用いて .bdf ファイル上に回路図を書いていく。 入力端子、出力端子などは あらかじめ用意されている。 また、AND・OR等のゲート素子も 登録されている。
具体的な方法 .vwf ファイルを作成してシミュレーションを行う。
フル・アダー呼び出しによる加算回路の論理合成 接続線の太さはデータのビット数が1bit か、それより大きなもので区別する。 このビット数による差を設定しないと、コンパイルすらできない。
シミュレーション結果 出力 q の項を見ると‘X’という不定形が出力されている。 接続の不良か、設定の不備か期待していた結果は得られなかった。 論理合成せずにHDL記述で実行した、フル・アダー呼び出しによる 4bit 加算回路
フル・アダーの論理合成結果
シミュレーション結果 A : L,H,L,H・・・・と交互に繰り返す B : H,L,H,L・・・・と交互に繰り返す CIN : 常に H
第2章 もう少し進んだVerilog HDL記述 2.1 電子サイコロ 修士1年 赤津 実幸
電子サイコロの構造 カウンターが1~6の値でループしており、 enableを0にした瞬間のカウンター値をサイコロの目で表現するmodule reset リセット。1の目を表示して停止 lamp[0] reset lamp[1] enable 1で回転 0で停止 lamp[2] enable lamp[3] lamp[4] ck クロック ck lamp[5] サイコロの目 3の場合 lamp[6] 電子サイコロのブロック図 ランプ lamp[0~6] 1 : ランプ点灯 0 : ランプ消灯 に対応 lamp[0] lamp[4] lamp[0] lamp[4] lamp[1] lamp[5] lamp[1] lamp[5] lamp[2] lamp[6] lamp[2] lamp[6] lamp[3] lamp[3] 対応表示ランプ
電子サイコロの各処理の説明 input ck, reset, enable if (reset = 1) カウンタ値cntを1に設定 else if (enable = 1) if(カウンタ値cnt = 3) cntを1に設定 else cntを1インクリメント Counter イベント pogedge ck or posedge reset reg [2:0] cnt 3bitレジスタ デコーダ 入力 cnt 出力 lamp ※ reset = 1ならcnt=1なので lamp[3]のみ1になり サイコロの目は1を表示 output [6:0] lamp
電子サイコロの各処理の説明 input ck, reset, enable Counter output [6:0] lamp functionを用いたデコーダ input ck, reset, enable function [6:0] dec functionのリターン値 7bitのデータを出力 Counter input [2:0] din C言語でいう仮引数。 3bitの変数をdinに代入 イベント pogedge ck or posedge reset reg [2:0] cnt 3bitレジスタ Case文によるdinの値での場合わけ din = 1 dec = 7b’0001000 din = 2 dec = 7b’1000001 din = 3 dec =7b’0011100 din = 4 dec=7b’1010101 din = 5 dec=7b’1110111 din = 6 dec=7b’1110111 din = その他 dec=不定値 デコーダ function dec 入力 3bit cnt 出力 7bit lamp lamp = dec( cnt ) 関数decに3bitカウンタ値cntを入れると7bitのlampに7bitのdecの値が代入される。 output [6:0] lamp
module saikoro 出力結果1 クロック周期 clk 50ns, 20MHz(=1/50ns) reset(1→0)タイミング 200ns enable(0→1)タイミング 800ns サイコロの目 1 2 3 4 5 6 1 2 3 4 5 6 1 ひげが立ち上がってしまう。1→2、3→4のタイミング こうなると、一瞬だけサイコロの値が変化してしまうところができてしまう。
module saikoro 出力結果2 問題の検証 カウンタcntと出力lampの出力タイミングが ほぼ同時 データの立ち上がり、 立ち下りのタイミングが重なるので 出力値が不安定になっている可能性がある
module saikoro 改善1 不定値を0化 カウンタcntが変化する不安定な区間はlampを0にする default = 7’bxxxxxxxを変更
module saikoro 改善1 変更後 変更前 変更後 サイコロの目 1 → 2 になるタイミングは改善された
module saikoro 改善1 変更後 3→4のタイミングの検証 011 100 ZOOM 6 5 4 ZOOM 6 カウンタ一瞬で値が変わるのではなく、bitが全て変化するのに時間がかかる。 lamp = dec(cnt)によりカウンタcntの変化に応じて出力lampも変化してしまう。
module saikoro 改善2 デコーダ処理 問題点 ・カウンタには値が完全に変化するまで時間がかかる ⇒その間のカウンタcntの値は不定値 ・カウンタcntの変化にすぐに応じてデコーダdecが処理して 出力lampに吐き出してしまう そこで ・カウンタcntが完全に変化したあとにデコーダdecで処理させて やればよい ⇒デコーダに処理のタイミングを与える ⇒カウンタはクロックの立ち上がりで処理するので 半クロック後にはカウンタの変化は終了しているので 半クロック後に1回デコーダ処理を行わせる ⇒イベントalways文を用いる always@(negedge ck)
module saikoro 改善2 変更後 クロックの立下り時にのみ処理を行うデコーダを作成 カウンタ変化後半クロック遅れて lamp出力される
module saikoro 改善2 比較 変更前 変更後 デコーダにカウンタを読み込むタイミング(半クロック遅延)が与えられたため カウンタの不定値範囲を読み込まなくなった
計算機工学特論A テキスト内容 2.2
2.2 電子錠
2.2.1 電子錠の仕様 入力 出力 7 8 9 4 5 6 1 2 3 ck reset lock tenkey [9:0] クローズ 2.2.1 電子錠の仕様 入力 出力 クロック(50Hz程度) ck 7 8 9 リセット reset 錠出力 4 5 6 lock テン・キー 10 tenkey [9:0] 1 2 3 クローズ クローズ・キー クロック close //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.2 電子錠の回路概要 =3 =6 =9 =5 ck lock tenkey ck close R S EN エンコーダ D Q CK 2.2.2 電子錠の回路概要 エンコーダ =3 =6 =9 EN D CK RES Q =5 R S ck lock //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。 tenkey ck close
2.2.3 電子錠のHDL記述 リスト2.3 module elelock(ck,reset,tenkey,close,lock); input ck,reset,close; input [9:0] tenkey; output lock; reg lock,ke1,ke2; reg [3:0] key [0:3];//レジスタ配列 wire match, key_enbl; parameter SECRET_3=4‘h5,SECRET_2 = 4’h9,SECRET_1 = 4‘h6,SECRET_0 = 4’h3;//定数 //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 レジスタ配列 reg [x1:x2] 名前 [y1:y2]; 多次元配列の一種。x1-x2+1bitをひとつの単位としてみなした一次元配列。要素数はy2-y1+1個。全体のサイズは(x1-x2+1)×(y2-y1+1)bit。アクセスはx1-x2+1bitを単位としてのみ可能で1bit単位ではアクセスできない。 ex) reg [7:0] u_byte [0:3]; //1byte(8bit)のu_byte[0]~[3]が宣言される u_byte[1] = 8’hff; //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 定数 parameter 名前 = 実態(数値); ex) parameter aka = 24’hff0000; reg [23:0] tmp; tmp = aka; とするとtmpに24‘hff0000が代入される //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 リスト2.3 暗証番号入力レジスタ リスト2.3 暗証番号入力レジスタ always @(posedge ck or posedge reset) begin if (reset = = 1'b1) begin key[3] <=4‘b1111;key[2] <=4’b1111; key[1] <=4‘b1111;key[0] <=4’b1111; end else if(close= =1'b1)begin key[3] <=4'b1111;key[2] <=4'b1111; key[1] <=4'b1111;key[0] <=4'b1111; else if (key_enbl= =1'b1) begin key[3] <= key[2]; key[2] <= key[1]; key[1] <= key[0]; key[0] <= keyenc(tenkey); リセット信号が来たらそれまでに入力された番号を消す。 クローズ信号が来たらそれまでに入力された番号を消す。 キー入力が来たら値を更新する //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。 入力されたキーから保持すべき値を返す関数
2.2.3 電子錠のHDL記述 リスト2.3 テンキー入力チャッタ取り用 リスト2.3 テンキー入力チャッタ取り用 always @(posedge ck or posedge reset) begin if(reset==1'b1) begin ke2 <= 1'b0; ke1 <= 1'b0; end else begin ke2 <= ke1; ke1 <= |tenkey; リセット信号が来たらキーが押されてない状態として暗証番号入力レジスタに通知する 1クロック前に押されてたキーの状態をke2に保存し今キーが押されているかを取得する。 //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 リスト2.3 電子錠出力 always @(posedge ck or posedge reset) begin if (reset==1'b1) lock <= 1'b0; else if (close==1'b1) lock <= 1'b1; else if (match==1'b1) end リセット信号が来たらロックを解除する クローズ信号が来たらロックする 暗証番号が一致したらロックを解除する //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 リスト2.3 テンキー入力エンコーダ function [3:0] keyenc; リスト2.3 テンキー入力エンコーダ function [3:0] keyenc; input [9:0] sw; case (sw) 10'b00000_00001: keyenc = 4'h0; 10'b00000_00010: keyenc = 4'h1; 10'b00000_00100: keyenc = 4'h2; 10'b00000_01000: keyenc = 4'h3; 10'b00000_10000: keyenc = 4'h4; 10'b00001_00000: keyenc = 4'h5; 10'b00010_00000: keyenc = 4'h6; 10'b00100_00000: keyenc = 4'h7; 10'b01000_00000: keyenc = 4'h8; 10'b10000_00000: keyenc = 4'h9; endcase endfunction //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.3 電子錠のHDL記述 リスト2.3 暗証番号一致信号 リスト2.3 暗証番号一致信号 assign match = (key[0]==SECRET_0) && (key[1]==SECRET_1) && (key[2]==SECRET_2) && (key[3]==SECRET_3); assign key_enbl = ~ke2 & ke1; endmodule 設定されている暗証番号と入力信号が一致すれば1を出力する ~はnotを表している。 //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.4 電子錠のシミュレーション //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。
2.2.4 電子錠のシミュレーション //で始まる1行は、行末までコメント扱い 文の終わりにはセミコロン;をつける。