4.2.2 4to1セレクタ

4.2.2 4to1セレクタ
4to1セレクタ
din[0]
din[1]
din[2]
din[3]
dout
sel
2
図4.9 4to1セレクタ
4本の信号から1本を選択する
「4to1セレクタ」を記述する。
図4.9にブロック図を示す。4ビッ
ト入力din[3:0]から、2ビット
の選択信号sel[1:0]によって1本
を選択し、doutに出力する。
sel[1:0]信号と入力din[3:0]の選
択の対応は
sel= =2’b00 ・・・din[0]
sel= =2’b01 ・・・din[1]
sel= =2’b10 ・・・din[2]
sel= =2’b11 ・・・din[3]
を選択
を選択
を選択
を選択
条件演算子による4to1セレクタ
//条件演算子による4to1セレクタ
module sel4to1_cond(din,sel,dout);
input[3:0] din;
input[1:0] sel;
output dout;
assign dout = (sel==2'h0)? din[0]:
(sel==2'h1)? din[1]:
(sel==2'h2)? din[2]: din[3];
endmodule
条件演算子
~?~:~を3個用いた4to1セレクタ。
条件演算子は入れ子構造(ネスティン
グ)が可能。条件演算子では、条件式
が真のときは?直後の値を、偽のとき
は:直後の値を演算結果とする。これ
により
if~
else if ~
else ~
を実現したことになる。
assign文一つで記述できるので一見簡潔。だが、選択される信号に論理式やファンクション
が入ってくると記述の可能性は低下する。また、論理合成ツールによっては、回路規模が
大きくなってしまうことがある。
if文による4to1セレクタ
//if文による4to1セレクタ
module sel4to1_if(din,sel,dout);
input [3:0] din;
input [1:0] sel;
output
dout;
function select;
input [3:0] din;
input [1:0] sel;
if (sel==2'h0)
select=din[0];
else if (sel==2'h1)
select=din[1];
else if (sel==2'h2)
select=din[2];
else
select=din[3];
endfunction
assign dout=select(din,sel);
endmodule
ここではif文を用いて、選択信号selの値を順次
比較する。一致した時点で、ファンクションselect
の戻り値を確定する。if~else if ~構造で一つ
のif文を形成している。
if文による4to1セレクタ
function select;
input [3:0] din;
input [1:0] sel;
if (sel==2'h0)
select=din[0];
else if (sel==2'h1)
select=din[1];
else if (sel==2'h2)
select=din[2];
else
select=din[3];
endfunction
function select;
input [3:0] din;
input [1:0] sel;
begin
if (sel==2'h0)
select=din[0];
if (sel==2'h1)
select=din[1];
if (sel==2'h2)
select=din[2];
if (sel==2'h3)
select=din[3];
end
endfunction
sel信号の起こりうる全て
の状態を記述している
のでこのように複数のif
文に分割できる。
begin~endは順次処理
ブロックと呼ばれている。
functionの中では input
などの宣言はいくつでも
記述できるが、実効部
は一文だけ許される。し
たがってこのように複数
の文を記述する場合は
begin~endで囲む。
case文による4to1セレクタ
//case文による4to1セレクタ
module sel4to1_case(din,sel,dout);
input [3:0] din;
input [1:0] sel;
output
dout;
function select;
input [3:0] din;
input [1:0] sel;
case(sel)
2'h0: select=din[0];
2'h1: select=din[1];
2'h2: select=din[2];
2'h3: select=din[3];
default:select=1'bx;
endcase
endfunction
assign dout=select(din,sel);
endmodule
多方向のセレクタについては、case文
を用いるとまとまる。
選択信号selと一致したラベルの行だけ
を実行する。見通しがよいので、多方向
のセレクタでは、もっぱらcase文を用いる。
ビット選択による4to1セレクタ
//ビット選択による4to1セレクタ
module sel4to1_bitsel(din,sel,dout);
input [3:0] din;
input [1:0] sel;
output dout;
assign dout=din[sel];
endmodule
図4.9の4to1セレクタを実現する場合、
おそらくビット選択による方法が一番シ
ンプルな記述スタイル。
多ビット信号のビット選択には、定数だけ
でなく変数を用いる事ができる。
4ビットの入力din[3:0]の1ビットを選択する時
assign dout=din[sel];
とすれば、選択信号selによって指定される
1ビットだけを選択できる。
3to1セレクタ
3本の信号から1本を選択し
出力する.
din[0]
din[1]
dout
din[2]
sel
2
図4.14 3to1セレクタ
if文による3to1セレクタ
//if文による3to1セレクタ
module sel3to1_if( din, sel, dout );
input [2:0]
din;
input [1:0]
sel;
output
dout;
function select;
input
[2:0] din;
input
[1:0] sel;
if ( sel==2'h0 )
select = din[0];
else if ( sel==2'h1 )
select = din[1];
else
select = din[2];
endfunction
assign dout = select( din, sel );
endmodule
図4.15
if文による3to1セレクタ
図4.11の4to1セレクタ
からsel==2’b11の場合
を取り除いただけ
case文による3to1セレクタ
//case文による3to1セレクタ
module sel3to1_case( din, sel, dout );
input
[2:0] din;
input
[1:0] sel;
output
dout;
function select;
input
[2:0] din;
input [1:0]
sel;
case ( sel )
2'h0:
select
2'h1:
select
2'h2, 2'h3: select
default:
select
endcase
endfunction
=
=
=
=
din[0];
din[1];
din[2];
1'bx;
図4.16
case文による3to1セレクタ
2'h2:
select = din[2];
2'h3:
select = din[2];
case ( sel )
2'h0:
2'h1:
default:
endcase
select = din[0];
select = din[1];
select = 1'bx;
assign dout = select( din, sel );
図4.15のif文による3to1と同一
endmodule
casex文による3to1セレクト
//casex文による3to1セレクト
//caxex文による3to1セレクト
module sel3to1_casex( din, sel, dout );
input
[2:0] din;
input
[1:0] sel;
output
dout;
図4.17
function select;
input
[2:0]
input
[1:0]
casex ( sel
2'b00:
2'b01:
2'b1x:
2'b1?:
endcase
endfunction
x、yを比較対象外にできる.
din;
sel;
)
select = din[0];
select = din[1];
select = din[2];
casez文による3to1セレクタ
casex文
図4.18 3種類のcase文の動作
case
x,xも含めて一致比較
casez
zはdon’t care
casex
x,zはdon’t’care
assign dout = select( din, sel );
endmodule
?をzと同じ意味に用いることもできる.
4.4 エンコーダ
藤井研究室 杉田 陽市
エンコーダの仕様
8入力のプライオリティ・エンコーダ
真理値表
din [7]
din [6]
din [5]
din [4]
din [3]
din [2]
din [1]
din [0]
優
先
順
位
高
dout [2]
dout [1]
dout [0]
din [7:0]
dout [2:0]
1xxxxxxx
01xxxxxx
001xxxxx
0001xxxx
00001xxx
000001xx
0000001x
0000000x
7
6
5
4
3
2
1
0

8個の1bit入力din[0]~din[7]から3bitのdoutを出力

dinのいずれか1ビットのみ'1'であることが前提

複数の入力が同時に'1'になっても出力を確定させるため,優先順位を付けてある

dinのMSB側の優先順位が高い
例
din: 11000000 → dout: 7
din: 01010000 → dout: 6
4.4.1 if文によるエンコーダ
if文によるエンコーダ
module encoder_if( din, dout);
input [7:0] din;
output [2:0] dout;
function [2:0] enc;
input [7:0] din;
if (din[7])
enc = 3'h7;
else if (din[6])
enc = 3'h6;
else if (din[5])
enc = 3'h5;
else if (din[4])
enc = 3'h4;
else if (din[3])
enc = 3'h3;
else if (din[2])
enc = 3'h2;
else if (din[1])
enc = 3'h1;
else
enc = 3'h0;
endfunction
assign dout = enc(din);
endmodule
③
①
① モジュールとポートの宣言
入力 8bit din
出力 3bit dout
② ファンクション encの定義
入力 8bit din
戻り値 3bit
else if ~ 構造でdinの上位ビットから比較す
ることで優先順位を付ける
上位ビットが'1'であれば戻り値確定

②
if (din[7])
・・・0,'x','z'のとき偽,0以外のとき真
if (din[7] == 1'b1)と同様
③ encの呼び出しとその結果のdoutへの代入
4.4.2 casex文によるエンコーダ
casex文
casex文によるエンコーダ
module encoder_casex( din, dout);
input [7:0] din;
output [2:0] dout;
function [2:0] enc;
input [7:0] din;
casex (din)
8'b1xxx_xxxx:
8'b01xx_xxxx:
8'b001x_xxxx:
8'b0001_xxxx:
8'b0000_1xxx:
8'b0000_01xx:
8'b0000_001x:
8'b0000_000x:
endcase
endfunction
enc
enc
enc
enc
enc
enc
enc
enc
=
=
=
=
=
=
=
=
3'h7;
3'h6;
3'h5;
3'h4;
3'h3;
3'h2;
3'h1;
3'h0;

使い方はcase文と同様

'x'の付いているビットは比較しない
casex (din)
8'b1xxx_xxxx: enc = 3'h7;

dinの8bit目(din[7])が1の場合,
3bit16進数の7を戻り値として返す

下位7bitは比較しない

_(アンダーバー)の有無,位置,個数は任意
assign dout = enc(din);
endmodule
特徴

If文によるものと比べ
可読性が良い
記述が簡潔
4.4.3 for文によるエンコーダ
for文によるエンコーダ
module encoder_for( din, dout);
input [7:0] din;
output [2:0] dout;
function [2:0] enc;
input [7:0] din;
integer i;
begin: LOOP
enc = 0;
for( i=7; i>=0; i=i-1)
if (din[i]) begin
enc = i;
disable LOOP;
end
end
endfunction


integer i
符号付きの32bit整数
begin: LOOP
・
・
・
end
begin~endで囲まれた順次処理
ブロックにラベル(名前)を付加
iを7から0まで変化させ,din[i]を上位ビットから比較
din[i]が1であった時点でencの戻り値を確定
assign dout = enc(din);
endmodule
disable LOOP;
名前付きブロックLOOPから抜け出す
特徴
ソフトウェアに近い記述スタイル
可読性が悪い
実際には使用しないほうが無難
4.4.4 always文によるエンコーダ
always文によるエンコーダ
module encoder_always( din, dout);
input [7:0] din;
output [2:0] dout;
reg [2:0] dout;
integer i;
always @(din)
begin: LOOP
dout = 0;
for ( i=7; i>=0; i=i-1)
if (din[i]) begin
dout = i;
discable LOOP;
end
end
for文を用いたエンコーダのfunctionをalwaysに置き換えた
もの

reg [2:0] dout;
always文の中の代入にはネット宣言
した信号を用いることが出来ないため,
doutをレジスト宣言
always @(din)
8bitの入力dinの内1bitでも変化したら,
常にalways以降を実行
入力が変化したら,すぐに出力の変化となる
endmodule
レジスタ変数を用いても組み合わせ回路となる
特徴
forループによるものに比べ,さらに可読性が悪い

実際には使用しないほうが無難
まとめ


今回説明した4つの記述法全てについてシミュレーションにより正常に動作することを確認した
casex文によるエンコーダが最良の記述法である