ご無沙汰です。今回は XC3S50A の クロックマネージャ DCM を cherry syn で使う方法を書くよ。とは言え DCM は高機能で、僕も良く分かってない^^まぁとにかく、入力クロックの周波数を何倍かしたり、何分の一かしたりできればかなり嬉しいので、それだけをやろう。あとは皆さん勉強して教えてね^^
process blink(clkin uint#1 clk, rstin uint#1 rst, out uint#1 led)
{
uint#1 st = 1;
while (1) {
uint#24 i;
for (i=0; i != 0xffffff; i++) ;
st = ~st;
led = st;
}
}
component DCM_SP(out uint#1 CLKFX, in uint#1 CLKIN, in uint#1 PSCLK, in uint#1 PSEN, in uint#1 PSINCDEC, in uint#1 RST, out uint#1 LOCKED);
component BUFG(in uint#1 I, out uint#1 O);
toplevel logicboy (in uint#1 pin<85> clk, in uint#1 pin<49> rst, out uint#1 pin<27> led)
{
com uint#1 clk16x, clk16xo;
com uint#1 zero;
com uint#1 rstn;
com uint#1 clk16xlocked;
rstn = ~rst;
zero = 0;
generic (
CLKFX_DIVIDE => 1,
CLKFX_MULTIPLY => 16,
CLKIN_PERIOD => 31.3,
CLK_FEEDBACK => "NONE"
)
DCM_SP(clk16xo, clk, zero, zero, zero, rstn, clk16xlocked);
BUFG(clk16xo, clk16x);
blink(clk16x, rst, led);
}
Xilinx のライブラリで用意されてるものをインスタンスして使いたいので、cherry syn で枠組みだけ書けるように component という構文を用意した。DCM_SP が DCM 本体、BUFG はグローバルクロックのバッファで、DCM の出力をこれにつなげて、クロックにする。とりあえずコンポーネントはこのまま書いてね。実はもっと色んなポートがあるんだけど、とりあえずこれだけ書けば動く。
トップレベルで、DCM_SP と BUFG をインスタンスするんだけど、DCM_SP の方では、付加情報として generic を書こう。DCM_SP の直前に generic の ( ) で囲まれたテキストが、そのまま VHDL に張り付けられる。CLKFX_DIVIDE では入力クロックを何分の一にするか(1 - 32 の整数)を、CLKFX_MULTIPLY では入力クロック何倍にするか(2 - 32 の整数)を指定する。この例では 16倍 になる。CLKIN_PERIOD は、入力クロックの周期を ns で指定する。本来は DCM はフィードバックをして使うんだけど、CLKFX だけを使う場合はフィードバックをしなくても良く、また、しない方がより低い周波数から使えるようになる。フィードバックしないと 200KHz から受け付ける。フィートバックすると 5MHz 以下は受け付けないかわりに、位相の制御とか色々できるようにはなる。
DCM_SP のパラメータで、PSCLK, PSEN, ISINCDEC は、L に縛っておかなければならないので、com で zero という信号を宣言し、0 に縛っておいて、それを指定した。また DCM_SP のリセット RST は正論理なので、com で rstn という信号を宣言し、rst の否定にして、それを指定した。LOCKED は、DCM がロックして周波数が安定したら H になる信号。
この例では、DCM_SP のクロック出力は clk16xo という com(信号)に入るけど、それをクロックバッファ BUFG に通して、クロック clk16x を作っている。
まぁこれと同じように書いて、CLKFX_DIVIDE, CLKFX_MULTIPLY, CLKIN_PERIOD を変えるだけで、色んな周波数を合成できるよ。
ちなみに XC3S50A では DCM を二つ、XC3S200Aなら 4 つ使えるよ。Spartan 6 シリーズでも、同じようにDCMが使えるよ。
なお、現在のバージョンの cherry syn では、zero や rstn を com で宣言せずに、パラメータとして直接 0、~rst と書けるようになっています。
DCM_SP(clk16xo, clk, 0, 0, 0, ~rst, clk16xlocked);
さぁ、これを使ってどんどん面白いものを作っちゃおう^^それでは皆さん、さようなら。