Part 1
요약·해설
공식 DTS include 3개, C API code, build 명령과 전체 sample log를 보존합니다.
MMCM
Up to 7
Rate · Phase · Duty
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
026BCDD9EA4A0CCFA23B03ED5302D23288A19995E2E8D7BBF785BA67A0F255FD
.. zephyr:code-sample:: clock-control-litex
:name: LiteX clock control driver
:relevant-api: clock_control_interface
Use LiteX clock control driver to generate multiple clock signals.
Introduction
************
This sample is providing an overview of LiteX clock control driver capabilities.
The driver uses Mixed Mode Clock Manager (MMCM) module to generate up to 7 clocks with defined phase, frequency and duty cycle.
Requirements
************
* LiteX-capable FPGA platform with MMCM modules (for example Digilent Arty A7 development board)
* SoC configuration with VexRiscv soft CPU and Xilinx 7-series MMCM interface in LiteX (S7MMCM module)
* Optional: clock output signals redirected to output pins for testing
Configuration
*************
Basic configuration of the driver, including default settings for clock outputs, is held in Device Tree clock control nodes.
.. literalinclude:: ../../../../../../dts/riscv/riscv32-litex-vexriscv.dtsi
:language: dts
:start-at: clk0: clock-controller@0 {
:end-at: };
:dedent:
.. literalinclude:: ../../../../../../dts/riscv/riscv32-litex-vexriscv.dtsi
:language: dts
:start-at: clk1: clock-controller@1 {
:end-at: };
:dedent:
.. literalinclude:: ../../../../../../dts/riscv/riscv32-litex-vexriscv.dtsi
:language: dts
:start-at: clock0: clock@e0004800 {
:end-at: };
:dedent:
This configuration defines 2 clock outputs: ``clk0`` and ``clk1`` with default frequency set to 100MHz, 0 degrees phase offset and 50% duty cycle. Special care should be taken when defining values for FPGA-specific configuration (parameters from ``litex,divclk-divide-min`` to ``litex,vco-margin``).
**Important note:** ``reg`` properties in ``clk0`` and ``clk1`` nodes reference the clock output number (``clkout_nr``)
Driver Usage
************
The driver is interfaced with the :ref:`Clock Control API <clock_control_api>` function ``clock_control_on()`` and a LiteX driver specific structure:
.. doxygenstruct:: litex_clk_setup
:project: Zephyr
| To change clock parameter it is needed to cast a pointer to structure ``litex_clk_setup`` onto ``clock_control_subsys_t`` and use it with ``clock_control_on()``.
| This code will try to set on ``clk0`` frequency 50MHz, 90 degrees of phase offset and 75% duty cycle.
.. code-block:: c
struct device *dev;
int ret;
struct litex_clk_setup setup = {
.clkout_nr = 0,
.rate = 50000000,
.duty = 75,
.phase = 90
};
dev = DEVICE_DT_GET(MMCM);
clock_control_subsys_t sub_system = (clock_control_subsys_t)&setup;
if ((ret = clock_control_on(dev, sub_system)) != 0) {
LOG_ERR("Set CLKOUT%d param error!", setup.clkout_nr);
return ret;
}
Clock output status (frequency, duty and phase offset) can be acquired with function ``clock_control_get_status()`` and clock output frequency only can be queried with ``clock_control_get_rate()``
In both getter functions, basic usage is similar to ``clock_control_on()``. Structure ``litex_clk_setup`` is used to set ``clkout_nr`` of clock output from which data is to be acquired.
Sample usage
************
This example provides a simple way of checking various clock output settings. User can pick one of 4 possible scenarios:
* Frequency range,
* Duty cycle range,
* Phase range,
* Setting frequency, duty and phase at once, then check clock status and rate,
Scenarios are selected by defining ``LITEX_CLK_TEST`` as one of:
* ``LITEX_TEST_FREQUENCY``
* ``LITEX_TEST_DUTY``
* ``LITEX_TEST_PHASE``
* ``LITEX_TEST_SINGLE``
Code is performed on 2 clock outputs with ``clkout_nr`` defined in ``LITEX_CLK_TEST_CLK1`` and ``LITEX_CLK_TEST_CLK2``. Tests are controlled by separate defines for each scenario.
Building
********
.. code-block:: none
west build -b litex_vexriscv zephyr/samples/drivers/clock_control
Drivers prints a lot of useful debugging information to the log. It is highly recommended to enable logging and synchronous processing of log messages and set log level to ``Info``.
Sample output
*************
.. code-block:: none
[00:00:00.200,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set rate: 100000000 HZ
[00:00:00.240,000] <inf> CLK_CTRL_LITEX: CLKOUT1: updated rate: 100000000 to 100000000 HZ
[00:00:00.280,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set duty: 50%
[00:00:00.320,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set phase: 0 deg
[00:00:00.360,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set rate: 100000000 HZ
[00:00:00.400,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set duty: 50%
[00:00:00.440,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set phase: 0 deg
[00:00:00.440,000] <inf> CLK_CTRL_LITEX: LiteX Clock Control driver initialized
*** Booting Zephyr OS build zephyr-v2.2.0-2810-g1ca5dda196c3 ***
Clock Control Example! riscv32
device name: clock0
clock control device is 0x40013460, name is clock0
Clock test
Single test
[00:00:00.510,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set rate: 15000000 HZ
[00:00:00.550,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set phase: 90 deg
[00:00:00.590,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set duty: 25%
[00:00:00.630,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set rate: 15000000 HZ
[00:00:00.670,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set duty: 75%
Getters test
CLKOUT0: get_status: rate:15000000 phase:90 duty:25
CLKOUT0: get_rate:15000000
CLKOUT1: get_status: rate:15000000 phase:0 duty:75
CLKOUT1: get_rate:15000000
Clock test done returning: 0
References
**********
- :ref:`litex-vexriscv`
Part 3
한국어 전문 번역
소개
이 sample은 LiteX clock control driver의 기능을 개괄합니다. Driver는 Mixed Mode Clock Manager(MMCM) module을 사용해 phase, frequency, duty cycle을 지정한 clock을 최대 7개까지 생성합니다.
요구 사항
- MMCM module을 갖춘 LiteX 지원 FPGA platform. 예를 들면 Digilent Arty A7 development board가 있습니다.
- VexRiscv soft CPU와 LiteX의 Xilinx 7-series MMCM interface(
S7MMCMmodule)를 포함한 SoC 구성. - 선택 사항: 시험을 위해 output pin으로 전달한 clock output signal.
구성
Clock output의 기본 설정을 포함한 driver의 기본 구성은 Device Tree clock control node에 들어 있습니다.
clk0: clock-controller@0 {
#clock-cells = <1>;
reg = <0>;
compatible = "litex,clkout";
clock-output-names = "CLK_0";
litex,clock-frequency = <11289600>;
litex,clock-phase = <0>;
litex,clock-duty-num = <1>;
litex,clock-duty-den = <2>;
litex,clock-margin = <1>;
litex,clock-margin-exp = <2>;
status = "disabled";
};
clk1: clock-controller@1 {
#clock-cells = <1>;
reg = <1>;
compatible = "litex,clkout";
clock-output-names = "CLK_1";
litex,clock-frequency = <22579200>;
litex,clock-phase = <0>;
litex,clock-duty-num = <1>;
litex,clock-duty-den = <2>;
litex,clock-margin = <1>;
litex,clock-margin-exp = <2>;
status = "disabled";
};
clock0: clock@e0004800 {
compatible = "litex,clk";
reg = <0xe0004800 0x4
0xe0004804 0x4
0xe0004808 0x4
0xe000480c 0x4
0xe0004810 0x4
0xe0004814 0x4
0xe0004818 0x4
0xe000481c 0x4>;
reg-names = "drp_reset",
"drp_locked",
"drp_read",
"drp_write",
"drp_drdy",
"drp_adr",
"drp_dat_w",
"drp_dat_r";
#clock-cells = <1>;
clocks = <&clk0 0>, <&clk1 1>;
clock-output-names = "CLK_0", "CLK_1";
litex,lock-timeout = <10>;
litex,drdy-timeout = <10>;
litex,divclk-divide-min = <1>;
litex,divclk-divide-max = <107>;
litex,clkfbout-mult-min = <2>;
litex,clkfbout-mult-max = <65>;
litex,vco-freq-min = <600000000>;
litex,vco-freq-max = <1200000000>;
litex,clkout-divide-min = <1>;
litex,clkout-divide-max = <126>;
litex,vco-margin = <0>;
status = "disabled";
};
이 구성은 clk0와 clk1이라는 두 clock output을 정의하며, 기본값은 frequency 100MHz, phase offset 0도, duty cycle 50%입니다. FPGA 전용 구성 값, 즉 litex,divclk-divide-min부터 litex,vco-margin까지의 parameter를 정의할 때는 특히 주의해야 합니다.
중요: clk0와 clk1 node의 reg property는 clock output 번호인 clkout_nr를 참조합니다.
Driver 사용법
Driver는 Clock Control API 함수 clock_control_on()과 LiteX driver 전용 구조체 litex_clk_setup으로 제어합니다.
struct litex_clk_setupClock control API와 연결하는 구조체입니다.
clkout_nr- 변경할 clock output 번호
rate- 설정할 frequency(Hz)
phase- Degree 단위 phase offset
duty- Percent 단위 clock signal duty cycle
Clock parameter를 바꾸려면 litex_clk_setup 구조체 pointer를 clock_control_subsys_t로 cast한 뒤 clock_control_on()과 함께 사용해야 합니다.
다음 code는 clk0의 frequency를 50MHz, phase offset을 90도, duty cycle을 75%로 설정하려고 시도합니다.
struct device *dev;
int ret;
struct litex_clk_setup setup = {
.clkout_nr = 0,
.rate = 50000000,
.duty = 75,
.phase = 90
};
dev = DEVICE_DT_GET(MMCM);
clock_control_subsys_t sub_system = (clock_control_subsys_t)&setup;
if ((ret = clock_control_on(dev, sub_system)) != 0) {
LOG_ERR("Set CLKOUT%d param error!", setup.clkout_nr);
return ret;
}
Clock output 상태인 frequency, duty, phase offset은 clock_control_get_status()로 얻을 수 있고, clock output frequency만 조회하려면 clock_control_get_rate()를 사용합니다.
두 getter 함수의 기본 사용법은 clock_control_on()과 비슷합니다. Data를 가져올 clock output의 clkout_nr를 지정할 때 litex_clk_setup 구조체를 사용합니다.
Sample 사용법
이 예제는 여러 clock output 설정을 간단히 확인하는 방법을 제공합니다. 사용자는 다음 네 가지 scenario 중 하나를 선택할 수 있습니다.
- Frequency 범위
- Duty cycle 범위
- Phase 범위
- Frequency, duty, phase를 한 번에 설정한 뒤 clock status와 rate 확인
LITEX_CLK_TEST를 다음 값 중 하나로 정의해 scenario를 선택합니다.
LITEX_TEST_FREQUENCYLITEX_TEST_DUTYLITEX_TEST_PHASELITEX_TEST_SINGLE
Code는 LITEX_CLK_TEST_CLK1과 LITEX_CLK_TEST_CLK2에 clkout_nr를 정의한 두 clock output에서 실행됩니다. 각 scenario는 별도의 define으로 제어합니다.
Build
west build -b litex_vexriscv zephyr/samples/drivers/clock_control
Driver는 유용한 debug 정보를 log에 많이 출력합니다. Logging과 log message의 synchronous processing을 활성화하고 log level을 Info로 설정할 것을 강력히 권장합니다.
Sample 출력
[00:00:00.200,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set rate: 100000000 HZ
[00:00:00.240,000] <inf> CLK_CTRL_LITEX: CLKOUT1: updated rate: 100000000 to 100000000 HZ
[00:00:00.280,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set duty: 50%
[00:00:00.320,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set phase: 0 deg
[00:00:00.360,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set rate: 100000000 HZ
[00:00:00.400,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set duty: 50%
[00:00:00.440,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set phase: 0 deg
[00:00:00.440,000] <inf> CLK_CTRL_LITEX: LiteX Clock Control driver initialized
*** Booting Zephyr OS build zephyr-v2.2.0-2810-g1ca5dda196c3 ***
Clock Control Example! riscv32
device name: clock0
clock control device is 0x40013460, name is clock0
Clock test
Single test
[00:00:00.510,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set rate: 15000000 HZ
[00:00:00.550,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set phase: 90 deg
[00:00:00.590,000] <inf> CLK_CTRL_LITEX: CLKOUT0: set duty: 25%
[00:00:00.630,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set rate: 15000000 HZ
[00:00:00.670,000] <inf> CLK_CTRL_LITEX: CLKOUT1: set duty: 75%
Getters test
CLKOUT0: get_status: rate:15000000 phase:90 duty:25
CLKOUT0: get_rate:15000000
CLKOUT1: get_status: rate:15000000 phase:0 duty:75
CLKOUT1: get_rate:15000000
Clock test done returning: 0
참고 자료
litex_vexriscvboard 문서
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.