# Understanding the PRCI clock path

**URL:** <https://forums.sifive.com/t/understanding-the-prci-clock-path/5827>\
**Category:** HiFive1 Rev B\
**Created:** [September 9, 2022, 4:12am UTC](https://forums.sifive.com/t/understanding-the-prci-clock-path/5827 "2022-09-09T04:12:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![pds](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@pds](https://forums.sifive.com/u/pds)\
**Post date:** [September 9, 2022, 4:12am UTC](https://forums.sifive.com/t/understanding-the-prci-clock-path/5827/1 "2022-09-09T04:12:51Z")

</div>

There have been numerous difficulties understanding strange behaviors when setting various configurations of the PRCI clock path of the FE310 SoC. These difficulties arise from two errors in the circuit diagram shown in Figure 2 of Section 6 of version 1p4 of the [Manual](https://sifive.cdn.prismic.io/sifive/b56b304f-cd2d-421b-9c14-6b35c33f172e_fe310-g002-manual-v1p4.pdf).

1. `pllbypass` mux ‘0’ input connects to output of `pllrefsel` mux, not the HFX clock source
2. `pllsel` mux ‘1’ input connects to output of `pllbypass` mux, not the PLL output

The diagram as shown in the Manual is below:

 ![prci-clock-diagram-per-spec](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/b/bf86d86466964a34aeaa9c18327fe5e9ff072516.jpeg)

The correct diagram is shown below:

 ![prci-clock-diagram-actual-asic](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/9/9938ec86f043a12d4eb65a7db22af6f899d36179.jpeg)

One of the clues, explaining (1), is a paragraph of Section 6.5:

 ![prci-refsel-paragraph](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/e/e591a75a76e1e7c631175a6d29e294bb9341478e.png)

The other clue is the fact that, when PLL is turned off (by `pllbypass`=1), the `pllsel` is able to control whether `hfclk` is driven only by HFR or by the selection of `pllrefsel`.

A few general rules that I discovered, that result in reliable and smooth operation:

- Change `pllrefsel` only when `pllbypass`=1 (PLL off) to prevent PLL unlock and possible latch-up
- Set `pllbypass`=0 (PLL on) only when HFR is enabled and `pllsel`=0, to allow PLL settle and give time to acquire lock condition
- Change `pllrefsel` only when HFR is enabled and `pllsel`=0, to prevent possible latch-up

Some of the earlier discussions related to this topic are  
[FE310-G002 v1p0 manual errata](https://forums.sifive.com/t/fe310-g002-v1p0-manual-errata/4751) (@pete_buechler @JimWilson),  
[Is it possible to brick the HiFive board?](https://forums.sifive.com/t/is-it-possible-to-brick-the-hifive-board/751/7) (@dvc @mwachs5  
@brucehoult),  
[Unable to read PRCI registers](https://forums.sifive.com/t/unable-to-read-prci-registers/3357) (@c0ntrarian @pds),  
[Clock generation and configuration](https://forums.sifive.com/t/clock-generation-and-configuration/2783) (@stef), and  
[Dtmcontrol\_scan stuck in infinite loop](https://forums.sifive.com/t/dtmcontrol-scan-stuck-in-infinite-loop/5813) (@tim @pds).

---

<div class="post-metadata">

**Author:** ![pds](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@pds](https://forums.sifive.com/u/pds)\
**Post date:** [September 9, 2022, 8:09am UTC](https://forums.sifive.com/t/understanding-the-prci-clock-path/5827/2 "2022-09-09T08:09:42Z")

</div>

Is it possible to brick the HiFive board? No. However, it is not always easy to completely and successfully reset it. As Tim explains in post above, the core is healthy and undamaged yet the Debug Module is simply stuck in an “always busy” condition, thus OpenOCD loops for a very long time and then gives up.

A typical case of unresponsiveness happens when a bad or buggy program is loaded into Flash (rom), rather than ram. It is very easy to get into seemingly “bricked” states when programming various configurations of the clock flow. Thus, when developing clock routines and algorithms, it is strongly recommended to do so re-targeting code to run only from RAM, where reset will always clear contents of RAM and give successful reset state.

Upon reset, code execution starts immediately. The required task is to completely reset the entire device and start into a `halt`’ed state. From then, you can erase the first few of the Flash’s blocks and everything is back to normal again.

Typical unresponsive connection from OpenOCD might look like this:

 ![prci-lockup-result](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/d/df72b64e7640fafba87ddfa0cd42fdf81dbad78e.jpeg)

A successful connection looks something like this:

 ![prci-success-reult](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/6/69bceacf6ca94a3682268a8f32291706e5b77db2.jpeg)

The erasing is done with a few simple steps of OpenOCD tcl commands:

```auto
echo [flash protect 0 0 2 off]
echo [flash erase_sector 0 0 2]
echo [flash protect 0 0 2 on]

```

The reset path of _HiFive_ and _LoFive_ boards involve the `AON` and `PMU` blocks and are shown below. The minor difference between boards at the JTAG reset input is not of much concern here:

 ![riscv-reset-path](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/0/03648cfa817d936f683d8796956254c4386f5fa0.png)

The time constant of R32 & C22 (or, R4 & C17 on the _LoFive_ board) is very, very long. To make matters worse, the negative-going pulse of `AON_PMU_OUT_0` upon reset is only about 400mS. During that short time, the voltage level at the enable input `EN` of the core `vdd_1V8` regulator only makes it down to about 1.2 v. This is not low enough to turn off the voltage regulator and completely reset the CPU.

This is shown in the scope trace below:

 ![prci-reset-path-1v8-enable](https://us1.discourse-cdn.com/flex020/uploads/sifive/original/2X/f/fdbf3c456376bd571b232644f4cb8b945acc27b4.jpeg)

When confronted with an apparently “bricked” board, the solution is simple: momentarily bridge C22 (or, C17 on the _LoFive_ board) with a tweezer or long-nose pliers. Then perform the JTAG connection as usual. One more press of the “Reset” button S2 (or, SW1 on the _LoFive_ board) might be needed to fully recover and connect the target into a _halt_’ed state.
