Learning BSV‎ > ‎Attributes‎ > ‎

Split Attribute

Overview

When a rule contains an if statement, the compiler has the option either of splitting the rule into two mutually exclusive rules, or leaving it as one rule for scheduling but using MUXes in the production of the action. Rule splitting can sometimes be desirable because the two split rules are scheduled independently, so non-conflicting branches of otherwise conflicting rules can be scheduled concurrently. Splitting also allows the split fragments to appear in different positions in the logical execution order, providing the effect of condition dependent scheduling.

Default Setting

Splitting is turned off by default for two reasons:

  • When a rule contains many if statements, it can lead to an exponential explosion in the number of rules. A rule with 15 if statements might split into 215 rules, depending on how independent the statements (and their branch conditions) are. An explosion in the number of rules can dramatically slow down (and cause other problems) for later compiler phases, particularly scheduling.
  • Splitting propagates the branch condition of each if to the predicates of the split rules. Resources required to compute rule predicates are reserved on every cycle. If a branch condition requires a scarce resource, this can starve other parts of the design that want to use that resource.

Usage

  • The split and nosplit attributes are used to override the default and/or compiler flag (-split-if).
  • The split attribute splits the statement immediately following the attribute statement, which must be an Action statement.
  • A split immediately preceeding a binding (e.g. let) statement is not valid.
  • If there are nested if statements within the split statement, it will continue splitting recursively through the branches of the statement.
  • The nosplit attribute can be used to disable rule splitting within nested if statements.

Example

module mkConditional#(Bit#(2) sel) ();
Reg#(Bit#(4)) a <- mkReg(0);
Reg#(Bool) done <- mkReg(False);

rule finish ;
(*split*)
if (a == 3)
begin
done <= True;
end
else
(*nosplit*)
if (a == 0)
begin
done <= False;
a <= 1;
end
else
begin
done <= False;
end
endrule
endmodule

Compiler Flag

To enable rule splitting for an entire design, use the compiler flag -split-if at compile time.  You can enable rule splitting for an entire design with the -split-if flag and then disable the effect for specific rules, by specifying the nosplit attribute before the rules you do not want to split.

Comments