Skip to content

Introduction: Modularization

Julian Oppermann edited this page Oct 25, 2021 · 4 revisions

CoreDSL 2 allows the separation of the core definition from the supported ISA through the InstructionSet entity, as shown below. An InstructionSet may contain the same sections as a Core, but can also inherit the contents of another InstructionSet. A Core then references a list of supported instruction sets after the provides keyword. Core and instruction set definitions may be distributed across several files, enabled by a simple import mechanism.

// File: base_isa.core_desc
InstructionSet BaseISA {
  architectural_state { /* ... */ }
  instructions        { I { /* ... */ } }
}
// File: my_cores.core_desc
import "base_isa.core_desc"

InstructionSet Ext_A  extends BaseISA { instructions { J  { /*...*/ } } }
InstructionSet Ext_AA extends Ext_A   { instructions { JJ { /*...*/ } } }
InstructionSet Ext_A  extends BaseISA { instructions { K  { /*...*/ } } }

Core Core1 provides Ext_A         {} // instructions: I and J
Core Core2 provides Ext_AA, Ext_B {} // instructions: I, J, JJ and K

Another modularization feature in CoreDSL 2 is the functions section, as illustrated in the code below. In may contain function definitions intended to be reused in multiple instructions, or, body-less function declaration marked with the extern keyword which are treated as implementation-specific black boxes, e.g. for raising an interrupt.

InstructionSet ISA {
  architectural_state { /* ... */ }

  functions {
    // helper function
    signed<5> saturate(signed<10> value, unsigned<4> limit) {
      if (value < -limit) return -limit;
      if (value >  limit) return  limit;
      return (signed<5>) value;
    }

    // black box
    extern void raise(int irq, int mcause);
  }

  instructions { /* ... */ } // instructions may call `saturate` and `raise`
}
Clone this wiki locally