Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on...
-
Upload
truongthien -
Category
Documents
-
view
220 -
download
0
Transcript of Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on...
![Page 1: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/1.jpg)
SkironExperiments in CPU Design in DMITHUN HUNSUR
1
![Page 2: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/2.jpg)
Agenda
Skiron
Why D?
Idioms
Ecosystem wonders
Lessons learnt
Annoyances
The Future
2
![Page 3: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/3.jpg)
Skiron
3
![Page 4: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/4.jpg)
State of Skiron
Hobbyist architecture to learn about design compromises + D
(ab)use
Currently focusing on instruction set simulation
32-bit RISC-inspired pure load-store architecture
Suite of associated software – currently primary product
No hardware implementation yet
Inspired by MIPS/ARM, while rapidly backing away from x86
Unlikely to take off
4
![Page 5: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/5.jpg)
Skiron Projects
Non-GC
common
emulator
GC
assembler
disassembler
debugger_backend
debugger_graphical
test_runner
docgen
5
![Page 6: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/6.jpg)
Current register layout
64 general-purpose integer registers
Last 5 are reserved:
z
ra
bp
sp
ip
6
![Page 7: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/7.jpg)
Current instruction set
~23 core instructions
Load/store
Arithmetic
Control flow
Not much else! Other features need to be implemented first
Pseudoinstructions compose useful functionality from opcodes
Example: stack manipulation
7
![Page 8: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/8.jpg)
Current opcode layouts
A
B
C
D
8
![Page 9: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/9.jpg)
But let’s leave it at that for now Plenty of work to be done on the CPU (simulation) side of things
Context switching
Multi-core systems
Proper IO
Interrupts
Instruction pipelining
Caching
Branch prediction
And so much more
If you’d like to learn more about CPU design compromises, check
out Andrew Waterman’s Design of the RISC-V Instruction Set
Architecture:
http://www.eecs.berkeley.edu/~waterman/papers/phd-thesis.pdf
9
![Page 10: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/10.jpg)
Why D?
10
![Page 11: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/11.jpg)
What about the other
languages?
11
![Page 12: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/12.jpg)
C/C++
Slow compile times
Obtuse syntax, especially with metaprogramming
Painful to use
Wrote a basic x86 ISA emulator in C++ a couple years ago
Metaprogramming is just awful
Classic example: enum <-> string
12
![Page 13: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/13.jpg)
Go
No.
13
![Page 14: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/14.jpg)
Rust
Serious competitor
Why not?
Metaprogramming not as in-depth
Slow compile times
Poor Windows support at the time
Slow to develop with
14
![Page 15: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/15.jpg)
Back to D
Nice, pragmatic language
Very powerful meta-programming
Very flexible
Can be used for all kinds of problems
Easy cross-platform
At least on x86
For the most part, it Just Works™
15
![Page 16: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/16.jpg)
D niceties that aren’t
metaprogramming
final switch
Binary constants
std.algorithm, std.range (with caveats)
Module system now, instead of 2014 2017 2020?
Pleasant syntax
Easy refactoring, especially with UFCS
static if
Unit tests
Fast compile times
Many other things!
16
![Page 17: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/17.jpg)
“One source of truth”
Design details need to be easy to change
Not easy by default
Handle assembler, emulator, documentation generation, all at
once
“Constrained” problem
Metaprogramming to the rescue
17
![Page 18: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/18.jpg)
Idioms
18
![Page 19: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/19.jpg)
Constants flow down
Changing one thing will update everything – constants directly drive
the code
Example:
Will drive
Number of available registers
Indices of the special registers
Documentation
Graphical debugger
Instruction encodings
enum RegisterBitCount = 6;
19
![Page 20: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/20.jpg)
Automatic serialization
Everyone and their dog has written a serialization library in D – it’s
very easy
Using mine:
mixin GenerateIdEnum!("DebugMessageId");
struct Initialize
{
uint memorySize;
uint coreCount;
uint textBegin;
uint textEnd;
mixin Serializable!DebugMessageId;
}
struct CoreGetState
{
uint core;
mixin Serializable!DebugMessageId;
}
20
![Page 21: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/21.jpg)
Memory mapped devices
Along similar lines to serialization
class Screen : Device {
@MemoryMap(0, AccessMode.Read)
uint width;
@MemoryMap(4, AccessMode.Read)
uint height;
@MemoryMap(8, AccessMode.ReadWrite)
Pixel[] pixels;
mixin DeviceImpl;
}
21
![Page 22: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/22.jpg)
The “descriptor enum” pattern
So let’s look at a problem
How do we define instructions in such a way that we can easily
utilise them?
What do we want to know about an instruction?
Its internal name (“AddA”)
Its user name (“add”)
Its index (4)
Its operand format (destination, source, source)
Its description (“Add `src1` and `src2` together, and store the result in `dst`.”)
22
![Page 23: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/23.jpg)
OpcodeDescriptor enumstruct OpcodeDescriptor{
string name;ubyte opcode;OperandFormat operandFormat;string description;
}
enum Opcodes{
…,AddA = OpcodeDescriptor(
"add",4, OperandFormat.DstSrcSrc,"Add `src1` and `src2` together,
and store the result in `dst`."),…
}
23
![Page 24: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/24.jpg)
What can you do with a descriptor
enum?
Let’s look at one of my favourite examples from the assembler:
// Construct the AA of pseudoinstructions => assemble functions
auto generatePseudoAssemble()
{
enum opcodes = [EnumMembers!Opcodes];
return "[%s]".format(
opcodes.filter!(a => a.operandFormat == OperandFormat.Pseudo)
.map!(a => `"%s": &assemble%s`.format(a.name, a.to!string()))
.join(", "));
}
this.pseudoAssemble = mixin(generatePseudoAssemble());
24
![Page 25: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/25.jpg)
Application in the emulator
This is used within the emulator to a similar, even more powerful
effect.
The “opcode dispatcher” will automatically dispatch the given
opcode to the function that simulates it (massively cut down):
string generateOpcodeSwitch() {
string s = `switch (instruction.opcode) {`;
foreach (member; EnumMembers!Opcodes) {
s ~= format(
`case Opcodes.%1$s.opcode:
switch (instruction.operandSize) {
case OperandSize.Byte4:
this.run%1$s!uint(opcode); break;
}
break;`, member.to!string());
s ~= "}\n";
return s;
}
void runAddA(Type = uint)(ref Core core, Opcode opcode)
{
core.setDst!Type(opcode,
core.getSrc1!Type(opcode) +
core.getSrc2!Type(opcode));
}
25
![Page 26: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/26.jpg)
Encoding definitions
Next problem: defining what a particular encoding for opcodes will
look like.
Want it to be self-explanatory
Why not use std.bitmanip.bitfields?
26
![Page 27: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/27.jpg)
DefineEncodingmixin DefineEncoding!(Encoding.A,
"Used for three-register instructions.",
ubyte, "opcode", OpcodeBitCount,
"The opcode number.",
Encoding, "encoding", EncodingBitCount,
"The encoding in use.",
Variant, "variant", VariantBitCount,
"The variant/modifier to apply to register3.",
Register, "register1", RegisterBitCount,
"The destination register.",
Register, "register2", RegisterBitCount,
"The first source register.",
Register, "register3", RegisterBitCount,
"The second source register.",
ubyte, "_padding", 2,
"",
OperandSize, "operandSize", OperandSizeBitCount,
"The sizes of the operands being used.",
);
struct EncodingDescriptor
{
struct Field
{
string type;
string name;
int size;
string description;
}
string name;
string description;
Field[] fields;
}
27
![Page 28: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/28.jpg)
EnumDocumented Documentation’s important
How do we keep enums documented?
Presenting EnumDocumented
mixin EnumDocumentedDefault!("Variant",
"Identity",
"Pass the operand through unchanged.",
"ShiftLeft1",
"Shift the operand 1 bit to the left.",
"ShiftLeft2",
"Shift the operand 2 bits to the left.",
);
28
![Page 29: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/29.jpg)
EnumDocumented output
enum Variant { Identity, ShiftLeft1, ShiftLeft2, }
enum VariantDocs = [
tuple(Variant.Identity, "Pass the operand through unchanged."),
tuple(Variant.ShiftLeft1, "Shift the operand 1 bit to the left."),
tuple(Variant.ShiftLeft2, "Shift the operand 2 bits to the left."),
];
foreach (pair; VariantDocs)
{
file.writefln("* **%s**", pair[0].to!string());
file.writefln(" * *Index*: %s", cast(uint)pair[0]);
file.writefln(" * *Description*: %s", pair[1]);
}
29
![Page 30: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/30.jpg)
Ecosystem wonders
30
![Page 31: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/31.jpg)
Hidden gems: multiSort
Was using the old Stack Overflow answer – a predicate that’s
unwieldy to work with:
descriptors.sort!((a,b) {
if (a.operandFormat != OperandFormat.Pseudo && b.operandFormat != OperandFormat.Pseudo) {
if (a.opcode < b.opcode) return true;
if (b.opcode < a.opcode) return false;
}
if (a.operandFormat == OperandFormat.Pseudo && b.operandFormat != OperandFormat.Pseudo)
return false;
if (b.operandFormat == OperandFormat.Pseudo && a.operandFormat != OperandFormat.Pseudo)
return true;
return a.name < b.name;
});
31
![Page 32: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/32.jpg)
Hidden gems: multiSort
And then I discovered multiSort:
auto descriptors = [EnumMembers!Opcodes];
descriptors.multiSort!(
(a, b) => a.operandFormat != OperandFormat.Pseudo &&
b.operandFormat == OperandFormat.Pseudo,
(a, b) => a.opcode < b.opcode,
(a, b) => a.name < b.name);
32
![Page 33: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/33.jpg)
GtkD
GtkD is very full-featured
Bindings feel practically native
33
![Page 34: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/34.jpg)
SimpleWindow is pretty simple https://github.com/adamdruppe/arsd
void handleWindow(ref State state, ScreenDevice screen, Keyboard keyboard, Thread processThread)
{
auto window = new SimpleWindow(screen.width, screen.height, "Skiron Emulator");
auto displayImage = new Image(window.width, window.height);
window.eventLoop(16, () {
if (!processThread.isRunning) {
window.close();
return;
}
copyImage(displayImage, screen);
auto screenPainter = window.draw();
screenPainter.drawImage(Point(0, 0), displayImage);
},
(KeyEvent ke) {
// Temporary
keyboard.key = ke.key;
});
}
34
![Page 35: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/35.jpg)
Visual D’s unexpected advantage
I use premake to generate my build files (thanks Manu!)
On Windows, I use Visual D
In recent versions, Visual Studio includes a profiler
So I thought… could it work?
35
![Page 36: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/36.jpg)
A horrifying realisation
It did work.
36
![Page 37: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/37.jpg)
37
![Page 38: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/38.jpg)
Lessons learnt
38
![Page 39: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/39.jpg)
Be careful with your delegates!
Taking a closer look at that code:
Look carefully at the arguments to the delegates, while pondering
the fact that Core is a struct
while (this.cores.any!(a => a.running) || this.client.isValid)
{
foreach (ref core; this.cores.filter!(a => a.running))
{
These delegates were copying the cores, getting the value, then
throwing them away
39
![Page 40: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/40.jpg)
Oops.
Two ways to fix:
Use ref
Rewrite so that filter/any aren’t used
40
![Page 41: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/41.jpg)
Fixed version 41
![Page 42: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/42.jpg)
Mixins aren’t always necessary
Classical case: converting enum-with-extensions to string
Could have used std.conv, but wanted @nogc + strings for non-
enum values
char[] registerName(Register index, char[] buffer) @nogc nothrow {
string generateRegisterIf() {
string ret = "";
foreach (member; EnumMembers!Register) {
string name = member.to!string();
ret ~= "if (index == Register.%s) return \"%s\".sformat(buffer);\n".format(
name, name.toLower());
}
ret ~= `else return "r%s".sformat(buffer, cast(ubyte)index);`;
return ret;
}
mixin(generateRegisterIf());
}
42
![Page 43: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/43.jpg)
Mixins aren’t always necessary
Wait a second.
char[] registerName(Register index, char[] buffer) @nogc nothrow {
foreach (member; EnumMembers!Register) {
enum loweredName = member.to!string.toLower.idup;
if (index == member)
return "%s".sformat(buffer, loweredName);
}
return "r%s".sformat(buffer, cast(ubyte)index);
}
43
![Page 44: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/44.jpg)
Top-level GC So there’s lots of code using the GC
But our emulator is @nogc!
44
![Page 45: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/45.jpg)
Top-level GC So there’s lots of code using the GC
But our emulator is @nogc!
void main(string[] args)
{
// Read config
// Validate user path
// Assemble if required
// Read and parse program
// Create IO devices
// Create state
// Create threads to drive state and debugger
// Spawn a window
// Wait for threads
// Print performance stats
}
45
![Page 46: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/46.jpg)
Potential improvementsBECAUSE D ISN’T PERFECT
46
![Page 47: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/47.jpg)
Metaprogramming improvements
Allowing symbols within declarations
Would really love to be able to do something like this:
enum $(name) {
foreach (member; __traits(allMembers, Module))
$(member),
}
47
![Page 48: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/48.jpg)
Metaprogramming improvements For comparison, what the actual version looks like:
string generateIdEnum(alias Module)(string name)
{
string s = "enum " ~ name ~ " : ubyte {";
foreach (member; __traits(allMembers, Module)) {
// WORKAROUND: Issue 15907
static if (member != "object" && member != "common") {
alias memberField =
Identity!(__traits(getMember, Module, member));
s ~= member ~ ",\n";
}
}
s ~= "}";
return s;
}
48
![Page 49: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/49.jpg)
Metaprogramming improvements
ubyte opcodeIndex = 0;enum Opcodes{
…,AddA = OpcodeDescriptor(
"add",opcodeIndex++, OperandFormat.DstSrcSrc,"Add `src1` and `src2` together, and store the result in `dst`."),
…}
CTFE state!
49
![Page 50: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/50.jpg)
AnnoyancesBECAUSE D REALLY ISN’T PERFECT
50
![Page 51: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/51.jpg)
GC
Classes are tied to the GC
Exceptions are tied to the GC
Delegates are tied to the GC
In theory can be used without the GC
Considerably less powerful
Or just not doable easily
51
![Page 52: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/52.jpg)
GC in the standard library
There’s lots of GC in the standard library!
So much reinvention to avoid landmines; examples relevant to
Skiron:
NonBlockingSocket
sformat
Containers
StopWatch (https://issues.dlang.org/show_bug.cgi?id=15991)
52
![Page 53: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/53.jpg)
Spot the bug
mixin EnumDocumentedDefault!("Variant",
"Identity",
"Pass the operand through unchanged."
"ShiftLeft1",
"Shift the operand 1 bit to the left.",
"ShiftLeft2",
"Shift the operand 2 bits to the left.",
);
53
![Page 54: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/54.jpg)
The Future
54
![Page 55: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/55.jpg)
Real hardware
Port to a FPGA so that it’s running on actual hardware
FPGAs are usually “programmed” in a hardware description
language like Verilog or VHDL
Obviously, not D
Would like to investigate generating HDL code from D
55
![Page 56: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/56.jpg)
Self-hosting
The Holy Grail
Be able to run the Skiron software suite on Skiron hardware
56
![Page 57: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/57.jpg)
Shoutouts
The GtkD team for making fantastic bindings
Brian Schott for creating std.experimental.lexer
Rainer Schuetze and team for Visual D
Manu Evans for premake, and for ardently pushing for a GC-
reduced D
57
![Page 58: Skiron Experiments in cpu design - DConfdconf.org/2016/talks/hunsur.pdf · Currently focusing on instruction set simulation 32-bit RISC-inspired pure load-store architecture ... If](https://reader030.fdocuments.in/reader030/viewer/2022020316/5b94e9bf09d3f252738dbdc2/html5/thumbnails/58.jpg)
Thanks for listening!Questions?
Email: [email protected]
Website: http://philpax.me
Twitter: @Philpax_
58