HWC/Verilog/応用編
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
* Verilog応用編 [#y90f1a4c]
#contents
*VHDLのgenerate文のような機能を実現するには? [#j0f6e905]
**if-generation [#h9b2d59d]
***Verilog-95 [#b0137036]
ややこしい使い方は,あきらめるしかない(?)~
単純な場合は,`ifdef~`else~`endif が適用できる。
>Example: 合成時に,ラッチとFFを選択する。
module register( CLK, D, Q );
input CLK, D;
output Q;
`define LATCH_ENABLE // この定義があるとラッチを生成
`ifdef LATCH_ENABLE
always @( CLK ) begin // ラッチ記述
if( !CLK )
Q <= D;
end
`else
always @( posedge CLK ) begin // FF記述
Q <= D;
end
`endif
endmodule
***Verilog 2001 [#nfec8f22]
generate文がちゃんとサポートされている。
generate if(条件1) ~ {else if(条件n)} ~ else endgenerate
module register( CLK, D, Q );
input CLK, D;
output Q;
parameter LATCH_ENABLE = 1; // この定義があるとラッ...
generate
if ( LATCH_ENABLE = 1 )
begin: sel_latch // block nameが必要
always @( CLK ) begin // ラッチ記述
if( !CLK )
Q <= D;
end
end
else
begin: sel_flipflop
always @( posedge CLK ) begin // FF記述
Q <= D;
end
end
endmodule
**for-generation [#hb165e11]
***Verilog-95 [#a3416bdf]
簡単な回路であれば,for文で代用可能。
>Example: 3入力加算器
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
input [7:0] IDAT0;
input [7:0] IDAT1;
input [7:0] IDAT2;
output [8:0] ODAT;
reg [7:0] add_sum; // フルアダーの加算出力
reg [7:0] add_carry; // フルアダーのキャリー出力
integer i; // for文で用いるループ...
function FULLADDER_SO; // フルアダーのSum out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_SO = AI ^ BI ^ CI;
end
endfunction
function FULLADDER_CO; // フルアダーのCarry out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_CO = ( AI & BI ) | ( BI & CI ) | ( CI & ...
end
endfunction
always @(IDAT0, IDAT1, IDAT2) begin // functio...
for( i = 0; i <= 7; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
***Verilog 2001 [#o243ed76]
generateが使える。
※Verilog 2001では for (..) begin の後にラベル(下の記述の"...
ModelSim (少なくとも6.0以前) ではラベルが無くてもコンパイ...
wire [7:0] add_sum, add_carry;
generate
genvar i; // for文で用いる変数
for( i = 0; i <= 7; i = i + 1 ) begin :label // ラベル
assign add_sum[i] = FULL_ADDER_SO( IDAT0[i], IDAT1...
assign add_carry[i] = FULL_ADDER_CO( IDAT0[i], IDAT1...
end
endgenerate
*グローバルな定数やファンクションを使うには? [#g1095edc]
コンパイラ指示子"`include"を用いて,外部ファイルをモジュ...
VHDLと違い定義ファイルはコンパイルする必要はないのでsim時...
-3入力加算器の例
パラメータ定義ファイル
// parameter.vh
parameter WIDTH = 'd8 // データ幅設定(8ビット)
ファンクション定義ファイル
// adder.vh
function FULLADDER_SO; // フルアダーのSum out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_SO = AI ^ BI ^ CI;
end
endfunction
function FULLADDER_CO; // フルアダーのCarry out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_CO = ( AI & BI ) | ( BI & CI ) | ( CI & AI...
end
endfunction
加算器モジュール
// add_3inp.v
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
`include "parameter.vh" // パラメータファイルのイ...
input [WIDTH-1:0] IDAT0;
input [WIDTH-1:0] IDAT1;
input [WIDTH-1:0] IDAT2;
output [WIDTH :0] ODAT;
reg [WIDTH-1:0] add_sum; // フルアダーの加算出力
reg [WIDTH-1:0] add_carry; // フルアダーのキャリ...
integer i; // for文で用いるループ...
`include "adder.vh" // ファンクションのインクル...
always @(IDAT0, IDAT1, IDAT2) begin
for( i = 0; i <= WIDTH-1; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
*VHDLのgeneric文のような機能を実現するには [#t7f09051]
***Verilog-95 [#ff81050d]
単にパラメータを上位階層から与えるだけであれば,以下のよ...
<モジュール名> #(Param0, Param1, …) <インスタンス名>(ポ...
#(…)で,下位モジュールのパラメータを定義順に割り当てる。
3入力加算器
// add_3inp.v
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
parameter WIDTH = 'd8 // パラメータの初期値
input [WIDTH-1:0] IDAT0;
input [WIDTH-1:0] IDAT1;
input [WIDTH-1:0] IDAT2;
output [WIDTH :0] ODAT;
reg [WIDTH-1:0] add_sum; // フルアダーの加算出力
reg [WIDTH-1:0] add_carry; // フルアダーのキャリ...
integer i; // for文で用いるループ...
`include "adder.h" // ファンクションのインクル...
always @(IDAT0, IDAT1, IDAT2) begin
for( i = 0; i <= WIDTH-1; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
加算器呼び出し
add_3inp #(16) u_add3inp( .IDAT0( IDAT0 ), // 16ビ...
.IDAT1( IDAT1 ),
.IDAT2( IDAT2 ),
.ODAT( ODAT ) );
***Verilog 2001 [#l9c52646]
ポート接続と同じように,パラメータ名による割り当てが可能。
add_3inp #(.WIDTH(16)) u_add3inp( .IDAT0( IDAT0 ), // WI...
.IDAT1( IDAT1 ),
.IDAT2( IDAT2 ),
.ODAT( ODAT ) );
*signed変数使用時の注意 [#q1350fa0]
signed変数を使うときはビット幅に注意
>Ex.
wire signed [7:0] s_idat0;
wire unsigned [7:0] u_idat1;
wire signed [15:0] add;
のとき,
s_idat0 = 8'h80; // -128
u_idat1 = 8'h00; // 0
add = s_idat0 + u_idat1; // -128 + 0
とすると,
add => 16'h0080 // +128
となってしまう。(右辺が符号ビット拡張されない)
add = s_idat0 + $signed( u_idat1 ); // 右辺第2項もsig...
とすれば,
add => 16'hff80 // -128
となる。
※ 参考サイト(SynopsysのSolvNet)
https://solvnet.synopsys.com/retrieve/015771.html
負の定数を10進で指定する記述
-8'd3 // OK
8'd-3 // Error
*2次元配列使用時の注意 [#q1350fa0]
行数の指定は"アドレスビット数"ではなく"行数"になる。
reg [19:0] ram [2047:0]; // 2048x20 のramモデル記述例。
*バレルシフタ [#f351c411]
**バレルシフタの回路を合成ツールに任せて大丈夫か? [#k614...
以下の2通りの記述(32ビット左バレルシフタ)をDesignCompiler...
-shifter1 : 合成ツールに任せる記述例
module shifter1(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
assign ODAT = IDAT >> SHIFT;
endmodule
-shifter2 : ある程度回路を明示的にした記述例
module shifter2(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
wire [31:0] mux1, mux2, mux3, mux4, mux5;
assign mux1 = ( SHIFT[0] ) ? { 1'b0, IDAT[31:1] } : ...
assign mux2 = ( SHIFT[1] ) ? { 2'b00, mux1[31:2] } : ...
assign mux3 = ( SHIFT[2] ) ? { 4'h0, mux2[31:4] } : ...
assign mux4 = ( SHIFT[3] ) ? { 8'h00, mux3[31:8] } : ...
assign mux5 = ( SHIFT[4] ) ? { 16'h0000, mux4[31:16] ...
assign ODAT = mux5;
endmodule
-合成結果
-- DesignCompiler 2004.12-SP4
-- タイミング制約無し
-- set_max_area 0
||shifter1|shifter2|
|エリア数|9459|10629|
|ワーストパス(ps)|2263.22|2262.06|
※ すくなくとも,DC2004.12で簡単なシフタを合成する場合,シ...
**符号を保持する右シフタ [#ucdf37b6]
signed変数を使えば,シフト演算子で符号も拡張してくれるか?
-shifter1s : 合成ツールに符号拡張も任せるつもりの記述例
module shifter1s(
input wire signed [31:0] IDAT,
input wire [4:0] SHIFT,
output wire signed [31:0] ODAT
);
assign ODAT = IDAT >> SHIFT;
endmodule
-shifter2s : 符号拡張を明示的にした記述例
module shifter2s(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
wire [31:0] mux1, mux2, mux3, mux4, mux5;
assign mux1 = ( SHIFT[0] ) ? { IDAT[31], IDAT[3...
assign mux2 = ( SHIFT[1] ) ? { {2{IDAT[31]}}, mux1[3...
assign mux3 = ( SHIFT[2] ) ? { {4{IDAT[31]}}, mux2[3...
assign mux4 = ( SHIFT[3] ) ? { {8{IDAT[31]}}, mux3[3...
assign mux5 = ( SHIFT[4] ) ? { {16{IDAT[31]}}, mux4[3...
assign ODAT = mux5;
endmodule
-上記と同じ条件で合成
-- shifter2sは当然期待通りの(符号が拡張される)シフタにな...
-- shifter1sは符号が拡張されない。合成結果はshifter1と同...
&size(20){&color(red){※ signed変数を使っても,シフト演算...
Verilog2001だと>>>で算術ビットシフトができる気がします。(...
*ステートマシン(FSM) [#kc5312ef]
Verilogでは,VHDLのようにステートをenumみたいな感じで列挙...
そのため,Verilogでステートマシンを記述する際は,各ステー...
-以下のステートマシンを記述する際の例
#ref(fsm.png)
--ステートマシン本体(VHDLとほぼ同じスタイル)
// ステートFF
always @( posedge CLK, negedge RST_X ) begin
if( !RST_X )
state <= S_IDLE;
else
state <= nextState;
end
// ステート遷移条件記述(ステートマシン出力は省略)
always @* begin
case( state ) // synopsys_parallel_case
S_IDLE :
if( start ) nextState <= S_STATE0;
else nextState <= S_IDLE;
S_STATE0 :
if( idle ) nextState <= S_IDLE;
else nextState <= S_STATE2;
S_STATE1 :
if( clear ) nextState <= S_STATE0;
else if( wait ) nextState <= S_STATE1;
else nextState <= S_STATE2;
S_STATE2 :
nextState <= S_STATE3;
S_STATE3 :
nextState <= S_STATE0;
default :
nextState <= S_IDLE;
endcase
end
--ステート割り付け(実際にはステートマシン本体より前に記述)
この割り付け如何でFSMの性能が決まる。~
代表的な割り付けは以下参照。
---グレイコードFSM~
基本的にはこれでよいと思う。完全にグレイコードにならない...
トグルするビットが少ないため,デコーダの組み合わせ回路が...
reg [2:0] state, nextState;
parameter S_IDLE = 3'b000;
parameter S_STATE0 = 3'b001;
parameter S_STATE1 = 3'b011;
parameter S_STATE2 = 3'b111;
parameter S_STATE3 = 3'b101;
---ワンホットFSM~
速度が要求される場合はこれがよいと思う。1ビットに1ステー...
FF数が多くなるので,面積は大きくなる。
reg [4:0] state, nextState;
parameter S_IDLE = 5'b00001;
parameter S_STATE0 = 5'b00010;
parameter S_STATE1 = 5'b00100;
parameter S_STATE2 = 5'b01000;
parameter S_STATE3 = 5'b10000;
---デコーダの回路を考慮したFSM~
近い機能のFSM出力に共通するビットを割り当てるなど,デコー...
&color(red){※ Synplify Proのデフォルト設定では,FSMを検出...
*ヘッダファイルの扱い [#y4e7edaa]
-ヘッダファイルの拡張子は.vhとし、絶対パス、相対パスの記...
>下記のようにファイル名のみ記述して、各ツールは+incdirオ...
`include "ヘッダファイル名"
-ヘッダファイルは1プロジェクトにつき、1つのDIRだけで管理...
>ファイル名は重複がおきないような命名ルールを守ること。
-RTLで用いるパラメータ類はブロックごとのヘッダファイルを...
***Verilog関係の各ツールとincludeファイルの指定方法 [#y6d...
:modelsim|vlog +incdir+<dir>
:nc verilog|ncverilog +incdir+<dirs>
:Design Compiler|自動認識
:Simplify|プロジェクトファイルで指定
:formality|read_verilog -vcs " +incdir+<dir> " ・・・VCSオ...
:Verdi(debussy)|verdi +incdir+<directory_name>
:leda|leda +incdir{+<directory>}
:opencad|未調査
上記の通り、各社で示し合わせたかのように殆どのツールで+in...
* `timescaleをRTLに書くかどうか [#tfaa144e]
本来不要ですが、`timescaleが在るソースと無いソースが混在...
warningになります。
-統一性を持たせるため共有ヘッダファイルに'timescaleを定義...
*クロックのassign [#z4c4d0f1]
クロック信号をassignするとΔ遅延が入りるので、テストベンチ...
クロック信号は基本的にクリーンであるべきなので、assignは...
例外として、ゲーテッドクロックがありますが、この場合は、F...
その際の遅延値はヘッダファイルに記述してください。
*レジスタ配列を使った記述 [#f6f002d9]
下のようなレジスタ配列を使った代入は、記述量に対して大き...
Design Compilerがまともな回路を生成してくれるようなので、...
always @(posedge clk)
ff_o[s] <= in;
integer u4b_sl;
always @( posedge CLK_SND, negedge RST_X )
・・・
for( u4b_sl=4'd0; u4b_sl<=4'd11; u4b_sl=u4b_sl+4'd1 )
stereo_link[u4b_sl] <= 1'b0;
・・・
integer u5b_ts;
always @*
begin
for( u5b_ts=5'd0; u5b_ts<=5'd23; u5b_ts=u5b_ts+5'd1 )
trmode_stereo[u5b_ts] <= stereo_link[u5b_ts[4...
end
-注意
FormalityではV-2004.03から多重配列に対応していますが、配...
このwarningは問題ないので無視してください。この記述は、他...
終了行:
* Verilog応用編 [#y90f1a4c]
#contents
*VHDLのgenerate文のような機能を実現するには? [#j0f6e905]
**if-generation [#h9b2d59d]
***Verilog-95 [#b0137036]
ややこしい使い方は,あきらめるしかない(?)~
単純な場合は,`ifdef~`else~`endif が適用できる。
>Example: 合成時に,ラッチとFFを選択する。
module register( CLK, D, Q );
input CLK, D;
output Q;
`define LATCH_ENABLE // この定義があるとラッチを生成
`ifdef LATCH_ENABLE
always @( CLK ) begin // ラッチ記述
if( !CLK )
Q <= D;
end
`else
always @( posedge CLK ) begin // FF記述
Q <= D;
end
`endif
endmodule
***Verilog 2001 [#nfec8f22]
generate文がちゃんとサポートされている。
generate if(条件1) ~ {else if(条件n)} ~ else endgenerate
module register( CLK, D, Q );
input CLK, D;
output Q;
parameter LATCH_ENABLE = 1; // この定義があるとラッ...
generate
if ( LATCH_ENABLE = 1 )
begin: sel_latch // block nameが必要
always @( CLK ) begin // ラッチ記述
if( !CLK )
Q <= D;
end
end
else
begin: sel_flipflop
always @( posedge CLK ) begin // FF記述
Q <= D;
end
end
endmodule
**for-generation [#hb165e11]
***Verilog-95 [#a3416bdf]
簡単な回路であれば,for文で代用可能。
>Example: 3入力加算器
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
input [7:0] IDAT0;
input [7:0] IDAT1;
input [7:0] IDAT2;
output [8:0] ODAT;
reg [7:0] add_sum; // フルアダーの加算出力
reg [7:0] add_carry; // フルアダーのキャリー出力
integer i; // for文で用いるループ...
function FULLADDER_SO; // フルアダーのSum out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_SO = AI ^ BI ^ CI;
end
endfunction
function FULLADDER_CO; // フルアダーのCarry out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_CO = ( AI & BI ) | ( BI & CI ) | ( CI & ...
end
endfunction
always @(IDAT0, IDAT1, IDAT2) begin // functio...
for( i = 0; i <= 7; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
***Verilog 2001 [#o243ed76]
generateが使える。
※Verilog 2001では for (..) begin の後にラベル(下の記述の"...
ModelSim (少なくとも6.0以前) ではラベルが無くてもコンパイ...
wire [7:0] add_sum, add_carry;
generate
genvar i; // for文で用いる変数
for( i = 0; i <= 7; i = i + 1 ) begin :label // ラベル
assign add_sum[i] = FULL_ADDER_SO( IDAT0[i], IDAT1...
assign add_carry[i] = FULL_ADDER_CO( IDAT0[i], IDAT1...
end
endgenerate
*グローバルな定数やファンクションを使うには? [#g1095edc]
コンパイラ指示子"`include"を用いて,外部ファイルをモジュ...
VHDLと違い定義ファイルはコンパイルする必要はないのでsim時...
-3入力加算器の例
パラメータ定義ファイル
// parameter.vh
parameter WIDTH = 'd8 // データ幅設定(8ビット)
ファンクション定義ファイル
// adder.vh
function FULLADDER_SO; // フルアダーのSum out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_SO = AI ^ BI ^ CI;
end
endfunction
function FULLADDER_CO; // フルアダーのCarry out
input AI; // 入力 A
input BI; // 入力 B
input CI; // キャリー入力
begin
FULLADDER_CO = ( AI & BI ) | ( BI & CI ) | ( CI & AI...
end
endfunction
加算器モジュール
// add_3inp.v
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
`include "parameter.vh" // パラメータファイルのイ...
input [WIDTH-1:0] IDAT0;
input [WIDTH-1:0] IDAT1;
input [WIDTH-1:0] IDAT2;
output [WIDTH :0] ODAT;
reg [WIDTH-1:0] add_sum; // フルアダーの加算出力
reg [WIDTH-1:0] add_carry; // フルアダーのキャリ...
integer i; // for文で用いるループ...
`include "adder.vh" // ファンクションのインクル...
always @(IDAT0, IDAT1, IDAT2) begin
for( i = 0; i <= WIDTH-1; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
*VHDLのgeneric文のような機能を実現するには [#t7f09051]
***Verilog-95 [#ff81050d]
単にパラメータを上位階層から与えるだけであれば,以下のよ...
<モジュール名> #(Param0, Param1, …) <インスタンス名>(ポ...
#(…)で,下位モジュールのパラメータを定義順に割り当てる。
3入力加算器
// add_3inp.v
module add_3inp( IDAT0, IDAT1, IDAT2, ODAT );
parameter WIDTH = 'd8 // パラメータの初期値
input [WIDTH-1:0] IDAT0;
input [WIDTH-1:0] IDAT1;
input [WIDTH-1:0] IDAT2;
output [WIDTH :0] ODAT;
reg [WIDTH-1:0] add_sum; // フルアダーの加算出力
reg [WIDTH-1:0] add_carry; // フルアダーのキャリ...
integer i; // for文で用いるループ...
`include "adder.h" // ファンクションのインクル...
always @(IDAT0, IDAT1, IDAT2) begin
for( i = 0; i <= WIDTH-1; i = i + 1 ) begin
add_sum[i] = FULLADDER_SO( IDAT0[i], IDAT1[i],...
add_carry[i] = FULLADDER_CO( IDAT0[i], IDAT1[i],...
end
end
assign ODAT = add_carry + {add_sum, 1'b0};
endmodule
加算器呼び出し
add_3inp #(16) u_add3inp( .IDAT0( IDAT0 ), // 16ビ...
.IDAT1( IDAT1 ),
.IDAT2( IDAT2 ),
.ODAT( ODAT ) );
***Verilog 2001 [#l9c52646]
ポート接続と同じように,パラメータ名による割り当てが可能。
add_3inp #(.WIDTH(16)) u_add3inp( .IDAT0( IDAT0 ), // WI...
.IDAT1( IDAT1 ),
.IDAT2( IDAT2 ),
.ODAT( ODAT ) );
*signed変数使用時の注意 [#q1350fa0]
signed変数を使うときはビット幅に注意
>Ex.
wire signed [7:0] s_idat0;
wire unsigned [7:0] u_idat1;
wire signed [15:0] add;
のとき,
s_idat0 = 8'h80; // -128
u_idat1 = 8'h00; // 0
add = s_idat0 + u_idat1; // -128 + 0
とすると,
add => 16'h0080 // +128
となってしまう。(右辺が符号ビット拡張されない)
add = s_idat0 + $signed( u_idat1 ); // 右辺第2項もsig...
とすれば,
add => 16'hff80 // -128
となる。
※ 参考サイト(SynopsysのSolvNet)
https://solvnet.synopsys.com/retrieve/015771.html
負の定数を10進で指定する記述
-8'd3 // OK
8'd-3 // Error
*2次元配列使用時の注意 [#q1350fa0]
行数の指定は"アドレスビット数"ではなく"行数"になる。
reg [19:0] ram [2047:0]; // 2048x20 のramモデル記述例。
*バレルシフタ [#f351c411]
**バレルシフタの回路を合成ツールに任せて大丈夫か? [#k614...
以下の2通りの記述(32ビット左バレルシフタ)をDesignCompiler...
-shifter1 : 合成ツールに任せる記述例
module shifter1(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
assign ODAT = IDAT >> SHIFT;
endmodule
-shifter2 : ある程度回路を明示的にした記述例
module shifter2(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
wire [31:0] mux1, mux2, mux3, mux4, mux5;
assign mux1 = ( SHIFT[0] ) ? { 1'b0, IDAT[31:1] } : ...
assign mux2 = ( SHIFT[1] ) ? { 2'b00, mux1[31:2] } : ...
assign mux3 = ( SHIFT[2] ) ? { 4'h0, mux2[31:4] } : ...
assign mux4 = ( SHIFT[3] ) ? { 8'h00, mux3[31:8] } : ...
assign mux5 = ( SHIFT[4] ) ? { 16'h0000, mux4[31:16] ...
assign ODAT = mux5;
endmodule
-合成結果
-- DesignCompiler 2004.12-SP4
-- タイミング制約無し
-- set_max_area 0
||shifter1|shifter2|
|エリア数|9459|10629|
|ワーストパス(ps)|2263.22|2262.06|
※ すくなくとも,DC2004.12で簡単なシフタを合成する場合,シ...
**符号を保持する右シフタ [#ucdf37b6]
signed変数を使えば,シフト演算子で符号も拡張してくれるか?
-shifter1s : 合成ツールに符号拡張も任せるつもりの記述例
module shifter1s(
input wire signed [31:0] IDAT,
input wire [4:0] SHIFT,
output wire signed [31:0] ODAT
);
assign ODAT = IDAT >> SHIFT;
endmodule
-shifter2s : 符号拡張を明示的にした記述例
module shifter2s(
input [31:0] IDAT,
input [4:0] SHIFT,
output [31:0] ODAT
);
wire [31:0] mux1, mux2, mux3, mux4, mux5;
assign mux1 = ( SHIFT[0] ) ? { IDAT[31], IDAT[3...
assign mux2 = ( SHIFT[1] ) ? { {2{IDAT[31]}}, mux1[3...
assign mux3 = ( SHIFT[2] ) ? { {4{IDAT[31]}}, mux2[3...
assign mux4 = ( SHIFT[3] ) ? { {8{IDAT[31]}}, mux3[3...
assign mux5 = ( SHIFT[4] ) ? { {16{IDAT[31]}}, mux4[3...
assign ODAT = mux5;
endmodule
-上記と同じ条件で合成
-- shifter2sは当然期待通りの(符号が拡張される)シフタにな...
-- shifter1sは符号が拡張されない。合成結果はshifter1と同...
&size(20){&color(red){※ signed変数を使っても,シフト演算...
Verilog2001だと>>>で算術ビットシフトができる気がします。(...
*ステートマシン(FSM) [#kc5312ef]
Verilogでは,VHDLのようにステートをenumみたいな感じで列挙...
そのため,Verilogでステートマシンを記述する際は,各ステー...
-以下のステートマシンを記述する際の例
#ref(fsm.png)
--ステートマシン本体(VHDLとほぼ同じスタイル)
// ステートFF
always @( posedge CLK, negedge RST_X ) begin
if( !RST_X )
state <= S_IDLE;
else
state <= nextState;
end
// ステート遷移条件記述(ステートマシン出力は省略)
always @* begin
case( state ) // synopsys_parallel_case
S_IDLE :
if( start ) nextState <= S_STATE0;
else nextState <= S_IDLE;
S_STATE0 :
if( idle ) nextState <= S_IDLE;
else nextState <= S_STATE2;
S_STATE1 :
if( clear ) nextState <= S_STATE0;
else if( wait ) nextState <= S_STATE1;
else nextState <= S_STATE2;
S_STATE2 :
nextState <= S_STATE3;
S_STATE3 :
nextState <= S_STATE0;
default :
nextState <= S_IDLE;
endcase
end
--ステート割り付け(実際にはステートマシン本体より前に記述)
この割り付け如何でFSMの性能が決まる。~
代表的な割り付けは以下参照。
---グレイコードFSM~
基本的にはこれでよいと思う。完全にグレイコードにならない...
トグルするビットが少ないため,デコーダの組み合わせ回路が...
reg [2:0] state, nextState;
parameter S_IDLE = 3'b000;
parameter S_STATE0 = 3'b001;
parameter S_STATE1 = 3'b011;
parameter S_STATE2 = 3'b111;
parameter S_STATE3 = 3'b101;
---ワンホットFSM~
速度が要求される場合はこれがよいと思う。1ビットに1ステー...
FF数が多くなるので,面積は大きくなる。
reg [4:0] state, nextState;
parameter S_IDLE = 5'b00001;
parameter S_STATE0 = 5'b00010;
parameter S_STATE1 = 5'b00100;
parameter S_STATE2 = 5'b01000;
parameter S_STATE3 = 5'b10000;
---デコーダの回路を考慮したFSM~
近い機能のFSM出力に共通するビットを割り当てるなど,デコー...
&color(red){※ Synplify Proのデフォルト設定では,FSMを検出...
*ヘッダファイルの扱い [#y4e7edaa]
-ヘッダファイルの拡張子は.vhとし、絶対パス、相対パスの記...
>下記のようにファイル名のみ記述して、各ツールは+incdirオ...
`include "ヘッダファイル名"
-ヘッダファイルは1プロジェクトにつき、1つのDIRだけで管理...
>ファイル名は重複がおきないような命名ルールを守ること。
-RTLで用いるパラメータ類はブロックごとのヘッダファイルを...
***Verilog関係の各ツールとincludeファイルの指定方法 [#y6d...
:modelsim|vlog +incdir+<dir>
:nc verilog|ncverilog +incdir+<dirs>
:Design Compiler|自動認識
:Simplify|プロジェクトファイルで指定
:formality|read_verilog -vcs " +incdir+<dir> " ・・・VCSオ...
:Verdi(debussy)|verdi +incdir+<directory_name>
:leda|leda +incdir{+<directory>}
:opencad|未調査
上記の通り、各社で示し合わせたかのように殆どのツールで+in...
* `timescaleをRTLに書くかどうか [#tfaa144e]
本来不要ですが、`timescaleが在るソースと無いソースが混在...
warningになります。
-統一性を持たせるため共有ヘッダファイルに'timescaleを定義...
*クロックのassign [#z4c4d0f1]
クロック信号をassignするとΔ遅延が入りるので、テストベンチ...
クロック信号は基本的にクリーンであるべきなので、assignは...
例外として、ゲーテッドクロックがありますが、この場合は、F...
その際の遅延値はヘッダファイルに記述してください。
*レジスタ配列を使った記述 [#f6f002d9]
下のようなレジスタ配列を使った代入は、記述量に対して大き...
Design Compilerがまともな回路を生成してくれるようなので、...
always @(posedge clk)
ff_o[s] <= in;
integer u4b_sl;
always @( posedge CLK_SND, negedge RST_X )
・・・
for( u4b_sl=4'd0; u4b_sl<=4'd11; u4b_sl=u4b_sl+4'd1 )
stereo_link[u4b_sl] <= 1'b0;
・・・
integer u5b_ts;
always @*
begin
for( u5b_ts=5'd0; u5b_ts<=5'd23; u5b_ts=u5b_ts+5'd1 )
trmode_stereo[u5b_ts] <= stereo_link[u5b_ts[4...
end
-注意
FormalityではV-2004.03から多重配列に対応していますが、配...
このwarningは問題ないので無視してください。この記述は、他...
ページ名: