-
Notifications
You must be signed in to change notification settings - Fork 3
Introduction: Syntax
The code below shows the CoreDSL2 description of a simple core implementing a subset of the RISC-V base ISA, shortened here for the purpose of highlighting the basic concepts used in the language.
The top-level entity, modelling a processor core, is the Core
.
It is split into several, optional sections.
In this example, only the architectural_state
(definition of implementation parameters, declarations of registers and address spaces) and instructions
(definitions of instruction encoding and behavior) sections are used.
Core definitions may also contain a functions
section that encapsulates utility or blackbox functionality (not shown here).
In general, the syntax follows the conventions of the C/C++ language family.
The manipulation of non-byte-sized data is common in the specification of instruction semantics, hence, we support arbitrary-precision integer types (with an explicit width specification in bits, e.g. unsigned<XLEN>
), bit literals (3'b010
), and bit-level operators such as bit ranges ([4:0]
) and concatenation (::
).
We borrow C++'s attribute notation to augment declarations and instructions with additional information, e.g. marking a register as the core's program counter with the attribute [[is_pc]]
.
Core My32bitRISCVCore {
architectural_state {
unsigned int REG_LEN = 32; // implementation parameter
unsigned int XLEN = 32; // implementation parameter
register unsigned<XLEN> X[REG_LEN]; // register file
register unsigned<XLEN> PC [[is_pc]]; // single register with attribute
unsigned<XLEN>& ZERO = X[0]; // register alias
extern unsigned<8> MEM[1<<XLEN]; // address space declaration
}
instructions {
LUI {
encoding: imm[31:12] :: rd[4:0] :: 7'b0110111;
behavior: if (rd != 0) X[rd] = imm;
}
JAL [[no_cont]] {
encoding: imm[20:20] :: imm[10:1] :: imm[11:11] :: imm[19:12] :: rd[4:0] :: 7'b1101111;
behavior: {
if (rd != 0)
X[rd] = (unsigned<XLEN>) (PC + 4);
PC += (signed) imm;
}
}
LW {
encoding: imm[11:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b0000011;
behavior: if (rd != 0) {
unsigned<XLEN> base = (unsigned<XLEN>) (X[rs1] + (signed) imm);
X[rd] = MEM[base] :: MEM[base + 1] :: MEM[base + 2] :: MEM[base + 3];
}
}
XOR {
encoding: 7'b0000000 :: rs2[4:0] :: rs1[4:0] :: 3'b100 :: rd[4:0] :: 7'b0110011;
behavior: if (rd != 0) X[rd] = X[rs1] ^ X[rs2];
}
// ... many more instructions, omitted for brevity
}
}