目次: RISC-V
以前HiFive Unleashedの動作周波数を調べました(2019年7月4日の日記参照)。今回はHiFive Unmatchedの動作周波数を調べます。Unmatchedに元々書き込んであるLinuxを起動したあと、PRCIレジスタ領域を見てみました。ダンプすると下記のようになっています。
0x10000000: 0xc0000000 0x820544c2 0x00000000 0x820d1180 0x10000010: 0x80000000 0x00000000 0x00000000 0x8206b982 0x10000020: 0x80000000 0x00000000 0x0000006f 0x00000004 0x10000030: 0x00000000 0x00000000 0x030187c1 0x00000000 0x10000040: 0x00000000 0x00000000 0x00000000 0x00000000 0x10000050: 0x82063bc2 0x80000000 0x00000000 0x00000000 0x10000060: 0x00000000 0x00000000 0x00000000 0x00000000
ビット31がPLL enableですので、オフセット0x4:core_pll, 0xc: ddr_pll, 0x1c: gemgxl_pll, 0x50: hfpclk_pllの設定が有効になっているようです。
いずれのPLL設定もビットフィールドの意味は同じで、[5:0] divr, [14:6] divf, [17:15] divqです。ビットフィールドが4bit境界にないので、PythonなどでPLLの設定値を表示させると楽だと思います。
SiFive U740の仕様書(7. Clocking and Reset)を見ると、PLLの出力周波数foutは
fout = fin / (div_r + 1) * 2 * (div_f + 1) / 2 ^ (div_q)
とのこと。PLLの入力finはいずれのPLLも同じでhfclkという26MHzの外部クロックです。
>> def dump(val): ... r = val & 0x3f ... f = (val >> 6) & 0x1ff ... q = (val >> 15) & 0x7 ... o = 26 / (r + 1) * 2 * (f + 1) / pow(2, q) ... print("r", r, "f", f, "q", q, "freq", o) >>> dump(0x820544c2) r 2 f 275 q 2 freq 1196.0 >>> dump(0x820d1180) r 0 f 70 q 2 freq 923.0 >>> dump(0x8206b982) r 2 f 230 q 5 freq 125.12499999999999 >>> dump(0x82063bc2) r 2 f 239 q 4 freq 260.0
出力結果を見るとcore_pll:1196MHz, ddr_pll:923MHz, gemgxl_pll:125.125MHz, hfpclk_pll: 260MHzという設定です。どうしてこの値なのかはわからないですけど、参考になります。
PLL設定に [20:18] rangeというフィールドがあるのですが、SiFiveの仕様書には説明が書かれていません。クロック周りはAnalog Bitsという会社のCLN28HPC Wide Range PLLを使っているようですが、PLLの詳細仕様はNDAを結ばないと知ることができません。うーむ、不親切……。
しかしSiFiveの人たちはLinuxのクロックドライバを作ってくれており、実装からPLLの仕様を窺い知ることができます。ドライバはlinux/drivers/clk/analogbits/wrpll-cln28hpc.cにあります。
/**
* __wrpll_calc_filter_range() - determine PLL loop filter bandwidth
* @post_divr_freq: input clock rate after the R divider
*
* Select the value to be presented to the PLL RANGE input signals, based
* on the input clock frequency after the post-R-divider @post_divr_freq.
* This code follows the recommendations in the PLL datasheet for filter
* range selection.
*
* Return: The RANGE value to be presented to the PLL configuration inputs,
* or a negative return code upon error.
*/
static int __wrpll_calc_filter_range(unsigned long post_divr_freq)
{
if (post_divr_freq < MIN_POST_DIVR_FREQ ||
post_divr_freq > MAX_POST_DIVR_FREQ) {
WARN(1, "%s: post-divider reference freq out of range: %lu",
__func__, post_divr_freq);
return -ERANGE;
}
switch (post_divr_freq) {
case 0 ... 10999999:
return 1;
case 11000000 ... 17999999:
return 2;
case 18000000 ... 29999999:
return 3;
case 30000000 ... 49999999:
return 4;
case 50000000 ... 79999999:
return 5;
case 80000000 ... 129999999:
return 6;
}
return 7;
}
単純に入力をswitch文で見ているだけです。説明を見るとpost-R-dividerとあるのでfin / (divr + 1) の周波数を見て決めれば良さそうですね。この情報を公開していただけるのは非常にありがたいのですが、NDAは大丈夫なんですかね……?大した情報ではないとはいえ、ちょっと心配になってしまいます。
< | 2021 | > | ||||
<< | < | 08 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | - | - | - | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)