Learning BSV‎ > ‎Attributes‎ > ‎

descending_urgency Attribute

Overview

When scheduling rules, the compiler picks a subset of rules that do not conflict with each other, so that they could all be executed within the same clock cycle. The order in which rules are considered for selection can affect the subset chosen. For example, suppose rules r1 and r2 conflict, and both are enabled. If r1 is considered first and selected, it may disqualify r2 from consideration, and vice versa.

Using the descending_urgency attribute the designer can specify that one rule is more urgent than another, so that it is always considered for scheduling before the other. The relationship is transitive, i.e., if rule r1 is more urgent than rule r2, and rule r2 is more urgent than rule r3, then r1 is considered more urgent than r3.

Attribute Syntax

(* descending_urgency = "r1, r2, r3" *)

The argument of the attribute is a string containing a comma-separated list of rule names. The example above specifies that r1 is more urgent than r2 which, in turn, is more urgent than r3.

The descending_urgency attribute can be placed:

  • immediately before the rule keyword in a rule...endrule- construct, in which case it can refer to any of the rules in the expression
  • immediately before the rules keyword in a rules...endrules construct, in which case it can refer directly to the rule or any other rules at the same level
  • immediately before the module keyword in a module...endmodule construct, in which case it can refer to any of the rules inside the module.

BSV Example

interface IfcCounter#(type t);
method t readCounter;
endinterface

typedef Bit#(16) CounterType;

(* synthesize,
always_ready = "readCounter",
always_enabled= "readCounter" *)
module counter (IfcCounter#(CounterType));

Reg#(CounterType) counter <- mkRegA(1);

/* The descending_urgency attribute will indicate the scheduling
order for the indicated rules. */
(* descending_urgency = "resetCounter, updateCounter" *)
// Next rule resets the counter to 1 when it reaches its limit.
rule resetCounter (counter == '1);
action
counter <= 1;
endaction
endrule

// Next rule updates the counter.
rule updateCounter;
action
counter <= counter + 1;
endaction
endrule

// Method to output the counter's value
method CounterType readCounter;
return counter;
endmethod
endmodule

Rule resetCounter conflicts with rule updateCounter because both try to modify the counter register when it contains all its bits set to one. Without any escending_urgency attribute, the updateCounter rule will obtain more urgency, meaning that if the predicate of resetCounter is met, only the rule updateCounter will fire. By setting the descending_urgency attribute the designer can control the scheduling in the case of conflicting rules.

Comments