2009/12/10

連載企画 CPU 実験教室 実践編 第 3 回 クロック モジュールの作り方

今回は、クロック モジュールの書き方のお話です。クロック モジュール自体の書き方は旧基板とそんなに変わりませんが、まだ手で回路につないでいる人も多いでしょう。今回はそんな手間を大幅に省いてくれる 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 の使い方

  1. プロジェクトに新しいファイルを追加しようとします

    新規ファイルの追加

  2. IP (CORE Generator & Architecture Wizard) を選択します

    ソース タイプを選択

  3. 必要なモジュールを選びます

    モジュールを選択

    確認画面

  4. 追加されたモジュールをダブル クリックして開きます

    モジュールを開く

  5. 編集します

    編集画面

クロックの逓倍については、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 件のコメント:

コメントを投稿