順序回路の応用として、シーケンサを設計しましょう。シーケンサの動作は一般的に状態遷移図によって表現されます。シーケンサは、マイクロプロセッサの動作を司る制御信号の生成に使われたり、いろいろな制御回路の中心的な役割を果たす順序回路といえます。
(a)制御回路
(b)タイミングチャート
(c)状態遷移図
シーケンサをゲートレベルで設計するには、カウンタ回路をフリッププロップによって構成したステートマシンにより、クロックに同期したタイミング信号を生成させます。 そして、そのタイミング信号に論理ゲートを組み合わせて、目的の制御信号を生成します。 Verilogでは「状態」の定義と「その状態の時に何をするのか」を記述するだけで、目的のステートマシンを表現できます。 つまり、状態遷移図とVerilogによる記述が1対1にほぼ対応することになります。
ここでは、クロック信号に同期して動作する制御回路を設計します。図(a)に目的の制御回路を、図(b)にタイミングチャートを、図(c)にその状態遷移図を示します。
この制御回路は特に意味を持った制御信号を出すわけではありません。 あくまで例題です。 制御信号への信号は、回路の動作を開始させるSTART、状態を初期状態に戻すRST、ある状態をスキップするJP、そしてクロック信号CLKです。同図(b)のタイミングチャートは、この制御回路の動作例を示しています。 図(c)の状態遷移図が全ての動作を表現しています。 なお、状態の遷移は全てクロック信号の立ち上がりで行うとします。
では、制御回路をVerilog-HDLで記述しましょう!
まず現在の状態を示す変数STATEを"reg"で宣言しておきます。 この場合状態は4状態ありますから2ビットで宣言します。 また、STATE変数が取り得る値として`S0、`S1、`S2、`S3の状態値を`defineで宣言しておきます。
次に状態遷移を記述します。 これはステートマシンと出力信号生成の2つの部分に分けて記述します。 コメントstate machineからの"always"がステートマシンの記述部分です。 一方、コメントcontrol signalからの"always"が各状態の時に出力する信号値を生成する組み合わせ回路となります。
`define S0 2'b00 // define state `define S1 2'b01 `define S2 2'b10 `define S3 2'b11 module sequencer ( START, JP, RESET, CLOCK, RA, RB, TM, O_STATE ); input START, JP, RESET, CLOCK; output RA, RB, TM; output [1:0] O_STATE; reg RA, RB, TM; reg [1:0] STATE; // state variable // state machine always @( posedge RESET or posedge CLOCK ) begin if( RESET == 1 ) // asynchronous reset STATE = `S0; else case ( STATE ) `S0 : if( START == 1 ) STATE = `S1; // transition start `S1 : if( JP == 1 ) STATE = `S3; // jump else STATE = `S2; `S2 : STATE = `S3; `S3 : STATE = `S0; // become initial state endcase // case( STATE ) end // control signals always @( STATE ) begin RA = 0; RB = 0; TM = 0; case ( STATE ) `S1 : begin RA = 1; end `S2 : begin RA = 1; RB = 1; end `S3 : begin TM = 1; end endcase // case( STATE ) end // always @ ( STATE ) assign O_STATE = STATE; endmodule // sequencer
シーケンサの最終的なシミュレーションを行い、完全にバグを取り除きましょう。 シミュレーションを行う際には、ALUの時と同様にテストフレームを作成する必要があります。 KITE-1 マイクロプロセッサを動作させるためのテストフレームとしてKITEマイクロプロセッサボードPLUS+と同様の動作をするテスト基板をVerilog-HDL記述で用意します。
テストフレームのVerilog-HDL記述 "sequencer_test.v"トップモジュールを作ります。このトップモジュールにおいて、sequencer モ ジュールと外部配線との接続を行います。
module sequencer_top ( ... ); input ...; output ...; ... assign RESET = ~RESET_L; sequencer sequencer1( ... ); assign STATE_L = ~STATE; assign RA_L = ~RA; assign RB_L = ~RB; assign TM_L = ~TM; endmodule
では、機能シミュレーションまで完成したシーケンサの Verilog-HDL 記述から、実装のために必要なゲートレベルの回路(ネットリスト)を作成しましょう。
論理合成は以下の手順で行います。
論理合成をかけるとたくさんのファイルを同時に生成します。 そのため、ファイルがごちゃごちゃにならないよう “syn”ディレクトリを作成し、論理合成の作業を行います。
このディレクトリに論理合成処理を行う一連の処理を記述したコマンドスクリプトを作成しておきます。以下に、そのコマンドスクリプトを示します。 ファイル名を "synthesis.scr" としてセーブします。
XACT = get_unix_variable("XACT") XILINX_LIB_PATH = XACT + /synopsys/libraries/syn SYNOPSYS = get_unix_variable("SYNOPSYS") SYNOPSYS_PATH = {SYNOPSYS + /libraries/syn} search_path = {../ ../src} + XILINX_LIB_PATH + search_path link_library = xilinx.db target_library = link_library symbol_library = class.sdb define_design_lib WORK -path ./WORK define_design_lib xblox_4000 -path SYNOPSYS + /libraries/dw/lib/fpga/xc4000 synthetic_library = {standard.sldb} edifout_write_properties_list = "instance_number port_location part" edifout_power_and_ground_representation = cell edifout_netlist_only = true bus_inference_style = "%s<%d>" bus_dimension_separator_style = "><" bus_naming_style = "%s<%d>" TOP = sequencer_top read -format verilog {"sequencer_top.v"} read -format verilog {"sequencer.v"} current_design TOP write -format db -hierarchy -output TOP + ".db" /* Add pads to the design. Make sure the current design is the top-level module. Change the default slew rate to SLOW (HIGH slew control). */ set_port_is_pad "*" set_pad_type -slewrate HIGH all_outputs() /* set_pad_type -exact BUFGP_F find(port, "CLOCK") */ insert_pads /* +++++++++++++++++++++++++++++++++++++++++++++++++ */ /* Compile the design */ /* +++++++++++++++++++++++++++++++++++++++++++++++++ */ /* Set the synthesis design constraints. */ ungroup -all -flatten remove_constraint -all set_fix_multiple_port_nets -all -buffer_constants report_compile_options /* Synthesize and optimize the design */ compile -map_effort high -verify -verify_effort high check_design /* +++++++++++++++++++++++++++++++++++++++++++++++++ */ /* Save the design */ /* +++++++++++++++++++++++++++++++++++++++++++++++++ */ /* Write the design report file */ report_timing > TOP + ".timing" /* Set the part type */ set_attribute TOP "part" -type string "4013PG223-4" /* Save design in EDIF format as.sedif */ write -format edif -hierarchy -output TOP + ".sedif" exit
また、verilog-HDLのファイルは上のディレクトリに配置したままで読み 取れるように "synthesis.scr" 内で設定されていますので、"*.v" ファイル を"syn" ディレクトリの中にコピーする必要はありません。
論理合成を行うには以下のコマンドを実行します。 なお、使用する論理合成ツールは SYNOPSYS 社製 Design Compiler FPGA です。
% dc_shell -f synthesis.scr |& tee synthesis.log
致命的なエラーがなければ論理合成は終了です。論理合成終了後、警告は多く 出る可能性がありますが、致命的な警告でないことを確認しておきます。問題 がなければ、以下のように拡張子が ".sedif" というファイルが作成されます。 これが、論理合成後のゲートレベルの回路(ネットリスト)になります。
論理合成がうまく終了すれば、Verilog のファイルにそれぞれ対応した sxnf ファイルが生成されます。もし、ファイルが足りない場合は、論理合成 がうまく終了していません。その場合は "synthesis.log"ファイル内に Error がないか、また無視できない Warning がないか確認して下さい。
[blade00]% ls -la *.sedif -rw-r--r-- 1 kuga 7901 May 29 11:02 sequencer_top.sedif [blade00]%
次は、配置・配線のステップになります。配置・配線を行う前に重要な設 定ファイルを作成する必要があります。それは、FPGA の端子と 入力した回路 の入出力端子の物理的な対応付けをすることです。この設定を行わなかった場 合、配置・配線処理プログラムは自動的に端子の割り付けを行います。今回は、 前もって用意されているテストボードを用いて後の動作検証を行いますので、 そのテストボードに合わせて端子の割当をしておく必要があります。
端子の割当は sequencer_top.cst ファイルを編集することで行います。 この制約ファイルでは、配置・配線する回路に対し遅延情報を付加したり、端子の割当を行うことができます。 ここでは、端子の物理配置のみ指定することにします。
sequencer_top.cst をエディタにかけ、以下のように記述しセーブしてください。
配置配線用端子制約条件ファイル "sequencer_top.cst"例えば、"D1"等の文字列はFPGAのピン番号に当たります。通常ICのピン番 号は純粋な数字ですが、このFPGAはPGAパッケージであるためアルファベット と数字の組合せになっています。
設定ファイルの設定が終ったら、
% xmake sequencer_top
のように、xmake コマンドを実行し配置・配線処理を始めます。今回作成 したシーケンサ程度では数分で正常に終了します。大規模な回路になると数十 分かかることもあります。この過程では主にxnfmerge、xnfprep、ppr、xdelay、 makebits の5つのプログラムが実行されます。
設計入力した回路は、変換後は複数のファイルに分かれています、xnfmerge はそれらのファイルを統合し一つのファイルにします。
xnfprep は使用した部品間の配線状況をチェックするプログラムです。 回路によっては使用しない端子とかが存在することもあるでしょう。 そのような箇所をチェックし不必要な部品を自動的に削除したりします。 xnfprep でエラーが発生することがあります。 その場合は、Show Log において xnfprep Log File を確認しエラー箇所を訂正してください。
pprは実際の配置配線処理を行います。 詳細なログは Show Log において Report File を確認しエラー箇所を訂正してください。 特にFPGA の最大実装規模に対してぎりぎりの論理資源を使用している場合など、配置や配線処理が不可能になる場合もあります。
xdelay は配置配線された回路がどの程度の周波数で動作することが可能なのか等の遅延情報を解析するためのツールです。 配線遅延情報が内部情報として付加されます。
makebits は配置配線されたデータを FPGA に転送する際に必要なファイルに変換するプログラムです。 最終的には、拡張子が ".bit" というファイルが作成されます。
makebits プログラムまで終了し、".bit"ファイルが正常に作成されていればOKです。 もし counter_top.out ファイル中にErrorの文字がある場合は配置・配線処理中にエラーがあったことを示します。 適宜誤りを修正してxmakeを再実行してください。
論理合成はうまくいきましたか?
最後は、動作確認を行います。では、検証ボードにこれまでの処理により作成したカウンタ回路のデータを転送し、シーケンサを動作させてみましょう。 検証ボードがつながっているワークステーションのターミナルにおいて,実装を行います。
検証ボードの電源を入れ、PROGRAMスイッチを押して検証ボード上のDONE LEDが転倒していることを確認します。 完成した設計データは"sequencer_top_xil.run"ディレクトリ内にある "sequencer_top.bit"ファイルです。 "counter_top_xil.run"ディレクトリに移動した後、以下のコマンドを入力します。
% xchecker ファイル名
Total of 11875 bytes transmitted. DONE signal went high. Transmitting time = N.NN secs
エラーの一例をあげると、"ERROR 124: Xchecker cable is not connected correctly to the system"は正しく接続されてないことを示します。 ワークステーションとKITEボードをつなぐダウンロード・ケーブルはちゃんとつながっていますか? KITEボードの電源はONですか? また、KITEボードがつながっているホストでxcheckerを実行していますか?
また、"ERROR 263: DONE signal went hi early. Check the design file and the device part."は、実装ボードのPROGRAMスイッチの左にあるスイッチがHOST側になっていない可能性があります。 HOST側にして下さい。
正しくシーケンサは動いているでしょうか? リセットを押すとステートはリセットされますか? JPスイッチをONにすると状態遷移はジャンプしますか? クロックダイアルをまわすと、状態遷移の速度が変わりますか? 動いてなければ、まず回路が間違っていると考えられます。 もう一度回路を見直し、実装手順を踏んでください。
以上で、このプログラムは終りです。お疲れさまでした。