AXI Clock Monitor#
The AXI Clock Monitor IP is used to measure clocks in the system. It allows up to 16 clocks to be measured at a time.
Features#
Can measure up to 16 clocks (set to 1 by default)
AXI-based configuration
Vivado and Quartus compatible
Files#
Name |
Description |
---|---|
Verilog source for the instance |
|
Tcl source describing the instance for Vivado |
|
Tcl source describing the instance for Quartus |
Configuration Parameters#
Name |
Description |
Default Value |
Choices/Range |
---|---|---|---|
ID |
Id. |
0 |
|
NUM_OF_CLOCKS |
Num Of Clocks. |
1 |
From 1 to 16. |
Interface#
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_awaddr |
AWADDR |
in [15:0] |
|
s_axi_awprot |
AWPROT |
in [2:0] |
|
s_axi_awvalid |
AWVALID |
in |
|
s_axi_awready |
AWREADY |
out |
|
s_axi_wdata |
WDATA |
in [31:0] |
|
s_axi_wstrb |
WSTRB |
in [3:0] |
|
s_axi_wvalid |
WVALID |
in |
|
s_axi_wready |
WREADY |
out |
|
s_axi_bresp |
BRESP |
out [1:0] |
|
s_axi_bvalid |
BVALID |
out |
|
s_axi_bready |
BREADY |
in |
|
s_axi_araddr |
ARADDR |
in [15:0] |
|
s_axi_arprot |
ARPROT |
in [2:0] |
|
s_axi_arvalid |
ARVALID |
in |
|
s_axi_arready |
ARREADY |
out |
|
s_axi_rdata |
RDATA |
out [31:0] |
|
s_axi_rresp |
RRESP |
out [1:0] |
|
s_axi_rvalid |
RVALID |
out |
|
s_axi_rready |
RREADY |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_aclk |
CLK |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
s_axi_aresetn |
RST |
in |
Physical Port |
Logical Port |
Direction |
Dependency |
---|---|---|---|
reset |
RST |
out |
Physical Port |
Direction |
Dependency |
Description |
---|---|---|---|
clock_* |
in |
Detailed Description#
The top module instantiates:
How to instantiate it in your project:
build this IP by going to the library/axi_clock_monitor folder and running make. For more details on building this, check out our guide. Another requirement is to have your desired project already built.
import the IP core to your block design, by opening the Block Design of the already built project, right-clicking in the Diagram then “Add IP” (or CTRL + I) and typing “axi_clock_monitor”
configure your IP by specifying how many clocks you want to monitor
connect the IP to the AXI interface
assign a base address to the IP core, such that it doesn’t overlap with other components
assign clock signals to the clock inputs
build again the HDL (now containing this module as well) by clicking “Generate Bitstream” from “Program and Debug” section in Vivado
Register Map#
DWORD |
BYTE |
Reg Name |
Description |
|||
---|---|---|---|---|---|---|
BITS |
Field Name |
Type |
Default Value |
Description |
||
0x0 |
0x0 |
PCORE_VERSION |
PCORE Version Registers |
|||
[31:0] |
PCORE_VERSION |
RO |
0x00000001 |
PCORE Version number |
||
0x1 |
0x4 |
ID |
ID Registers |
|||
[31:0] |
ID |
RW |
0x00000000 |
Instance identifier number |
||
0x3 |
0xc |
NUM_OF_CLOCKS |
Number of Clocks Registers |
|||
[31:0] |
NUM_OF_CLOCKS |
RW |
0x00000008 |
Number of clock inputs |
||
0x4 |
0x10 |
OUT_RESET |
Reset Control Registers |
|||
[0:0] |
RESET |
RW |
0x0 |
Control the out reset signal |
||
0x10 + 0x1*n |
0x40 + 0x4*n |
CLOCK_n |
Measured clock_n Where n is from 0 to 15. |
|||
[31:0] |
CLOCK_n |
RO |
0x00000000 |
Measured frequency of clock_n |
Software Guidelines#
Note
Only no-OS software is supported.
We use software to access the core’s registers to get the data from the IP.
The following example contains a simple function that reads all the info from the IP and prints it on the serial terminal:
1void clock_monitor_info (uint32_t core_base_addr, uint32_t axi_clock_speed_mhz) {
2 uint32_t clock_ratio = 0;
3 uint32_t clk1_addr = 0x40;
4 uint32_t n_clocks = 0;
5 uint32_t info_var = 0;
6 uint8_t n = 0;
7
8 info_var = axi_io_read(core_base_addr);
9 printf("PCORE_VERSION = %d\n", info_var);
10
11 info_var = axi_io_read(core_base_addr, 4);
12 printf("ID = %d\n", info_var);
13
14 n_clocks = axi_io_read((core_base_addr, 12));
15 printf("n clocks = %d\n", n_clocks);
16
17 info_var = axi_io_read(core_base_addr, 16);
18 printf("RESET OUT = %d\n", info_var);
19
20 while (n < n_clocks & n < 16) {
21 clock_ratio = axi_io_read((core_base_addr, clk1_addr + 4*n));
22
23 if (clock_ratio == 0) {
24 printf("Measured clock_%d: off\n", n);
25 } else {
26 printf("Measured clock_%d: %d MHz\n", n,
27 (clock_ratio * axi_clock_speed_mhz + 0x7fff) >> 16);
28 }
29 n++;
30 }
31}
To call the function, consider the following parameters:
core_base_addr will take the value of the base address set at step 5 of the HDL instantiation
axi_clock_speed_mhz will be the reference frequency. In most cases, we assume this parameter to be 100 [MHz]