Skip to content

Rationale

Julian Oppermann edited this page May 22, 2022 · 6 revisions

Associativity in the context of arbitrary-precision integer operations

In C, arithmetic operations usually produce a result with the same type of at least one the operands, e.g. the sum of two unsigned values is again an unsigned value, implicitly truncating the result. This is different in CoreDSL: here, in case of an unsigned addition, the result type is one bit wider than the width of the operands.

In consequence, different evaluations of an expression result in differently-typed ASTs, as illustrated below for the sum of four 3-bit literals. (For brevity, u<N> == unsigned<N>)

┌───────────────────────────────────────────────┐ ║ ┌───────────────────────────────────────────────┐
│         ((3'd1 + 3'd1) + 3'd1) + 3'd1         │ ║ │         (3'd1 + 3'd1) + (3'd1 + 3'd1)         │
└───────────────────────────────────────────────┘ ║ └───────────────────────────────────────────────┘
                                                  ║
                            + : u<6>              ║
                                │                 ║
                   ┌────────────┴───────────┐     ║
                   │                        │     ║
               + : u<5>                     │     ║                     + : u<5>
                   │                        │     ║                         │
          ┌────────┴───────────┐            │     ║            ┌────────────┴────────────┐
          │                    │            │     ║            │                         │
      + : u<4>                 │            │     ║        + : u<4>                  + : u<4>
          │                    │            │     ║            │                         │
     ┌────┴───────┐            │            │     ║      ┌─────┴──────┐            ┌─────┴──────┐
     │            │            │            │     ║      │            │            │            │
INT : u<3>   INT : u<3>   INT : u<3>   INT : u<3> ║ INT : u<3>   INT : u<3>   INT : u<3>   INT : u<3>

One could argue that the addition (or analogously, any other binary operation) is no longer associative, because the 4-bit, 5-bit and 6-bit + are different operators. However, we believe this semantic is unproblematic (and even desirable) in practice:

  1. The numeric result is guaranteed to be exact, as no implicit under-/overflows happen.
  2. The arithmetic rules uniquely define the result types and required conversions for any (either implicit, or explicit through parentheses) evaluation order.
  3. The compiler's ability to reassociate such expression trees remains unimpaired.

Last-assigment-is-effective semantics for implementation parameters

An earlier version of this specification mandated that all assignments to implementation parameters must evaluate to a unique constant value in the context of a specific core definition. We changed this behavior to make the last assignment effective (see the elaboration rules).

The main reason for this change was that the old behavior was deemed too restrictive. For example, it prevents declaring the 64-bit RISC-V base ISA as a sub-ISA of the 32-bit ISA, which is the natural way to organize these instruction sets.

However, an advantage of the old behavior was that it gave stronger guarantees to instruction set definitions. For example, an ISA could assign an XLEN parameter to 32, to enforce it would only be used as part of 32-bit cores. We plan to bring back such kinds of constraints in a more general way with assertions in a future version of the language.