-
Notifications
You must be signed in to change notification settings - Fork 4
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 CoreDef
.
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.
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]]
.
CoreDef 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
}
}