sifive / benchmark-coremark

CoreMark® is an industry-standard benchmark that measures the performance of central processing units (CPU) and embedded microcrontrollers (MCU).
Other
10 stars 5 forks source link

HiFive1 RevB: Ticks and Elapsed Time yield low Frequency #9

Open lyellread opened 4 years ago

lyellread commented 4 years ago

After compiling and running coremark for the HiFive1 RevB, I get unexpected results as far as the clock speed as calculated from the provided data. Results:

2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 1720290432
Total time (secs): 107
Iterations/Sec   : 46
Iterations       : 5000
Compiler version : GCC8.3.0
Compiler flags   : -O3 -DPERFORMANCE_RUN=1 -DMAIN_HAS_NOARGC=1 -DHAS_STDIO -DHAS_PRINTF -DHAS_TIME_H -DUSE_CLOCK -DHAS_FLOAT=0 -Wno-maybe-uninitialized -O2 -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-tree-dominator-opts -fno-reg-struct-return -fno-rename-registers --param case-values-threshold=8 -fno-crossjumping -freorder-blocks-and-partition -fno-tree-loop-if-convert -fno-tree-sink -fgcse-sm -fno-strict-overflow -DITERATIONS=5000  -Wl,--gc-sections -Wl,-Map,coremark.map -nostartfiles -nostdlib -L/home/lread/lread/freedom-e-sdk/bsp/sifive-hifive1-revb/install/lib/release/ -T/home/lread/lread/freedom-e-sdk/bsp/sifive-hifive1-revb/metal.ramrodata.lds -Wl,--start-group -lc -lgcc -lm -lmetal -lmetal-gloss -Wl,--end-group
Memory location  : STACK
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0xbd59
Correct operation validated. See README.md for run and reporting rules.

Based on those results, I would calculate the CPU Frequency to be 1720290432/107 = 16077480 = 16MHz. This processor frequency is low of what I would expect out of this board (advertised to run up to 320MHz) - is the number of ticks scaled to optimize register/storage use somehow?

mwachs5 commented 4 years ago

By default the board is running from an on-board oscillator, not the on-chip PLL, Which is at 16MHz. You need to run startup code to enable the PLL and switch over to that frequency.

lyellread commented 4 years ago

That makes alot of sense! Thank you!

lyellread commented 4 years ago

I have read this manual about how the hifive1 revb uses the 16MHz Crystal, and how to switch to the PLL, and I wrote up the following code (adding it to the portable_init function in core_portme.c), based on the opposite of what happens in this guide.

//defines for the clock-change process, part of portable_init
#define PRCI_CTRL_ADDR 0x10008000UL
#define PRCI_PLLCFG (0x0008)
#define PLL_BYPASS(x) (((x) & 0x1) << 18)

mmio_write_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG, mmio_read_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG) ^ PLL_BYPASS(1));

Now when the benchmark runs, the output to the console is garbled (I suspect as a result of having successfully changed the core frequency and the UART driver being designed for 16MHZ). The drivers provided in the freedom-e-sdk are only provided (as far as I can tell) are only provided as .o files, thus if my assumption about their hardcoded nature is correct, I cannot change them easily.

Do you happen to know where some of this "startup code" is located that sets the clock source to PLL, and maybe UART source files as well?

Thank you! ~Lyell

Matthias-Raudonis commented 4 years ago

You can use the cpu and uart functions of this repo: https://github.com/kjarvel/hifive1revb_wifi

I have read this manual about how the hifive1 revb uses the 16MHz Crystal, and how to switch to the PLL, and I wrote up the following code (adding it to the portable_init function in core_portme.c), based on the opposite of what happens in this guide.

//defines for the clock-change process, part of portable_init
#define PRCI_CTRL_ADDR 0x10008000UL
#define PRCI_PLLCFG (0x0008)
#define PLL_BYPASS(x) (((x) & 0x1) << 18)

mmio_write_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG, mmio_read_u32(PRCI_CTRL_ADDR, PRCI_PLLCFG) ^ PLL_BYPASS(1));

Now when the benchmark runs, the output to the console is garbled (I suspect as a result of having successfully changed the core frequency and the UART driver being designed for 16MHZ). The drivers provided in the freedom-e-sdk are only provided (as far as I can tell) are only provided as .o files, thus if my assumption about their hardcoded nature is correct, I cannot change them easily.

Do you happen to know where some of this "startup code" is located that sets the clock source to PLL, and maybe UART source files as well?

Thank you! ~Lyell