Learning BSV‎ > ‎Advanced Bluespec‎ > ‎

Configuration Register

According to term-rewriting semantics, rules are thought of as firing one-at-a-time sequentially. From this point of view, the scheduling logic's job is not only to generate this sequence, but also to divide it into chunks so all the rules in a chunk fire during the same clock. However, if the rules involve several registers, all the reads from these registers will be performed near the beginning of the clock cycle, and all the writes at the end. It follows that any rule (or method) which reads a register must occur earlier in the TRS sequence as one which writes to it. Sometimes, however, there are conflicting constraints between two rules; if so, those two rules cannot be scheduled in the same chunk (that is, fired on the same clock).

An example of this occurs when a method writes to a register which is read by an internal rule. For technical reasons a module's methods are always scheduled first in a chunk, earlier than all the internal rules, and with greater urgency. So this combination of circumstances would mean that the method and the rule can never fire together, and the rule will be inhibited whenever the method fires.

This situation often occurs with configuration registers, which are written by an external method (connected to some local bus mechanism) which writes the register on every clock (though the value written changes very rarely). In this case a rule reading the register would be starved out completely, and never fire.

The ConfigReg package was designed to address this issue. A ConfigReg has the same interface as a Reg, and the Verilog implementation for mkReg and mkConfigReg are also identical. The only difference is the scheduling information specified in the import "BVI" wrapper -- for ordinary registers, reads must occur before writes (as described above); for ConfigReg's, the two methods are conflict-free, so reads may occur before or afterwards.

Thus the conflict described above no longer occurs. The downside is that the value read, whether the read occurs before or after a write within the same chunk, will always be the contents of the register at the beginning of the chunk -- that is, the value might be slightly stale. In the case of configuration registers this does not normally matter -- the parameters are set very rarely, and a one-clock difference is acceptable.