今回は、クロック モジュールの書き方のお話です。クロック モジュール自体の書き方は旧基板とそんなに変わりませんが、まだ手で回路につないでいる人も多いでしょう。今回はそんな手間を大幅に省いてくれる Core Generator のお話です。
今回はようやくまともな話が聞けそうね |
クロック周りの UCF
CONFIG PART=5VLX50TFF1136-1; NET CLK_48M LOC=H17 | IOSTANDARD=LVTTL; # CLK48M NET CLK_66M LOC=J16 | IOSTANDARD=LVTTL; # MCLK1 NET CLK_RST LOC=H18 | IOSTANDARD=LVTTL; # XRST
クロックは適当に 66MHz と 48MHz の信号を取り出してやれば OK です。リセットボタンは上の CLK_RST と書いてあるやつで、押されていない状態で 1、押されている状態で 0 です (low-active)。
クロック モジュールの基本
基本は、上の UCF で外部のチップから IO を通して入れた生のクロック信号を、一度 ibufg を通して、DCM に入れ、適当にループを形成して、必要な信号を bufg を通して、実際のクロックとして使用します。今まではこれを手で書いていたわけですが、Core Generator を使うとこれをまとめて簡単に作ってくれるのです。
Core Generator の使い方
- プロジェクトに新しいファイルを追加しようとします
- IP (CORE Generator & Architecture Wizard) を選択します
- 必要なモジュールを選びます
- 追加されたモジュールをダブル クリックして開きます
- 編集します
クロックの逓倍については、CLKFX 系にチェックを入れないと編集する画面が出ないので注意してください
Core Generator で作ったモジュールは、[Processes] ペインにある [View HDL Instantiation Template] でインターフェース、[View HDL Source] でシミュレーション用ソース コードが見れるよっ! |
リセット ボタン・LOCK 信号について
LOCK について
DCM は、クロックを入れ始めた始めのほうはまだ信号が不安定です。クロックの周期が安定しているとは限りません。そこで、LOCK という信号を出して、LOCK=1 になったら使用してよいというような感じで作られています。LOCK をリセット信号にあわせて出力するとよいでしょう。
リセット信号を混ぜたクロック モジュールの書き方
リセット信号と LOCK 信号をかませることを想定して、以下のようにさっき生成したモジュールを使用すればいいことが分かります。roc は相変わらず使えます。
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.vcomponents.all;
entity clockgenerator is
port (
globalclk : in std_logic; -- 生の 66MHz グローバル クロックを入れる
globalrst : in std_logic; -- リセット ボタンの信号を入れる
clock66 : out std_logic;
clock133 : out std_logic;
clock133_180 : out std_logic;
reset : out std_logic); -- いろいろまとめてリセット信号として出す。
end clockgenerator;
architecture behavioral of clockgenerator is
component clockgen -- Core Generatorで生成したもの
port (
clkin_in : in std_logic;
rst_in : in std_logic;
clkin_ibufg_out : out std_logic;
clk0_out : out std_logic;
clk2x_out : out std_logic;
clk2x180_out : out std_logic;
locked_out : out std_logic);
end component;
signal rst : std_logic;
signal rocrst : std_logic;
signal lock : std_logic;
begin
roc_inst : roc port map (o => rocrst); -- roc は新基板でもそのまま使える。
rst <= rocrst or (not globalrst); -- ここでは、リセット信号で DCM ごと初期化しているが、DCM は初期化しないのも手
reset <= rst or (not lock);
inst_clockgen : clockgen port map(
clkin_in => globalclk,
rst_in => rst,
clkin_ibufg_out => open, -- 明示的に open 使っても無駄に警告されます。ise バカだろ
clk0_out => clock66,
clk2x_out => clock133,
clk2x180_out => clock133_180,
locked_out => lock);
end behavioral;
最後に
もし何か意見・質問ございましたら下のコメント欄にお寄せください。もしコメントが寄せられたら今後の励みになるので是非ください。
0 件のコメント:
コメントを投稿