Pydgin for RISC-V:
A Fast and Productive Instruction-Set Simulator
Berkin Ilbeyi
In collaboration with Derek Lockhart (Google), and Christopher Batten
3rd RISC-V Workshop, Jan 2016

Cornell University
University
CornellComputer Systems Laboratory
Computer Systems Laboratory

Motivation

Software
Instruction-Set Architecture
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Performance
Interpretive:

1-10 MIPS (1-10 days)

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Performance
Interpretive:

1-10 MIPS (1-10 days)

Typical DBT: 100s MIPS (1-3 hours)

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Performance
Interpretive:

1-10 MIPS (1-10 days)

Typical DBT: 100s MIPS (1-3 hours)
QEMU DBT: 1000 MIPS (0.5 hours)

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Productivity

Performance- Develop

Interpretive:

1-10 MIPS (1-10 days)- Extend

Typical DBT: 100s MIPS (1-3 hours)- Instrument

QEMU DBT: 1000 MIPS (0.5 hours)

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Productivity

Performance- Develop

Interpretive:

1-10 MIPS (1-10 days)- Extend

Typical DBT: 100s MIPS (1-3 hours)- Instrument

QEMU DBT: 1000 MIPS (0.5 hours)

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Productivity

Performance- Develop

Interpretive:

1-10 MIPS (1-10 days)- Extend

Typical DBT: 100s MIPS (1-3 hours)- Instrument

QEMU DBT: 1000 MIPS (0.5 hours)

Vendor
Proprietary ISA

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Productivity

Performance- Develop

Interpretive:

1-10 MIPS (1-10 days)- Extend

Typical DBT: 100s MIPS (1-3 hours)- Instrument

QEMU DBT: 1000 MIPS (0.5 hours)

RISC-V Foundation
RISC-V

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Motivation
Productivity

Performance- Develop

Interpretive:

1-10 MIPS (1-10 days)- Extend

Typical DBT: 100s MIPS (1-3 hours)- Instrument

QEMU DBT: 1000 MIPS (0.5 hours)

RISC-V Foundation
RISC-V
Specialized
RISC-V
Specialized
RISC-V

Software
Instruction-Set Simulator
HardwarePydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

1 / 16

Productivity

Performance

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language

Instruction Set
Interpreter in C
with DBT

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language

Instruction Set
Interpreter in C
with DBT

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Architectural
Description
Language

Performance[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT[Simit-ARM2006] J.D’Errico and W.Qin. Constructing Portable Compiled Instruction-Set Simulators — An ADL-Driven Approach. DATE’06.
[Wagstaff2013] H. Wagstaff, M. Gould, B. Franke, and N.Topham. Early Partial Evaluation in a JIT-Compiled, Retargetable Instruction
Set Simulator Generated from a High-Level Architecture Description. DAC’13.
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Architectural
Description
Language

Performance[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT

Dynamic Language
Interpreter in C
with JIT Compiler

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT

Key Insight:
Similar productivity-performance challenges forbuilding high-performance interpreters ofdynamic languages.
(e.g. JavaScript, Python)

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

Dynamic Language
Interpreter in C
with JIT Compiler

2 / 16

Productivity

Performance

Architectural
Description
Language[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT

Key Insight:
Similar productivity-performance challenges forbuilding high-performance interpreters ofdynamic languages.
(e.g. JavaScript, Python)

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

Dynamic Language
Interpreter in C
with JIT Compiler

2 / 16

Productivity

Performance

Architectural
Description
Language[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT

Dynamic-Language
Interpreterin RPython

RPythonTranslation
Toolchain

Dynamic Language
Interpreter in C
with JIT Compiler

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language[SimIt-ARM2006][Wagstaff2013]

Instruction Set
Interpreter in C
with DBT

Dynamic-Language
Interpreterin RPython

RPythonTranslation
Toolchain

Dynamic Language
Interpreter in C
with JIT Compiler

Meta-Tracing JIT:
makes JIT generation generic across languages
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language

Instruction Set
Interpreter in C
with DBT

PydginRPythonTranslation
Toolchain

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Productivity

Performance

Architectural
Description
Language

Instruction Set
Interpreter in C
with DBT

PydginRPythonTranslation
Toolchain

JIT ≈ DBT
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

2 / 16

Pydgin Architecture Description Language
Architectural State

State
Encoding

Instruction Encoding
Semantics

Instruction Semantics

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

3 / 16

Pydgin Architecture Description Language
Architectural State

State
Encodingclass State( object ):Semantics

def __init__( self, memory, reset_addr=0x400 ):self.pc = reset_addr
self.rf = RiscVRegisterFile()
self.mem = memory# optional state if floating point is enabled
if ENABLE_FP:
self.fp= RiscVFPRegisterFile()
self.fcsr = 0

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

4 / 16

Pydgin Architecture Description Language
Instruction Encoding

State
Encoding

Semantics

encodings = [# ...
['xori', 'xxxxxxxxxxxxxxxxx100xxxxx0010011'],['ori', 'xxxxxxxxxxxxxxxxx110xxxxx0010011'],['andi', 'xxxxxxxxxxxxxxxxx111xxxxx0010011'],['slli', '000000xxxxxxxxxxx001xxxxx0010011'],['srli', '000000xxxxxxxxxxx101xxxxx0010011'],['srai', '010000xxxxxxxxxxx101xxxxx0010011'],['add', '0000000xxxxxxxxxx000xxxxx0110011'],['sub', '0100000xxxxxxxxxx000xxxxx0110011'],['sll', '0000000xxxxxxxxxx001xxxxx0110011'],# ...
]Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

5 / 16

Pydgin Architecture Description Language
Instruction Semantics

State
Encoding

Semantics

def execute_addi( s, inst ):s.rf[inst.rd] = s.rf[inst.rs1] + inst.i_imm
s.pc += 4
def execute_sw( s, inst ):addr = trim_xlen( s.rf[inst.rs1] + inst.s_imm )s.mem.write( addr, 4, trim_32( s.rf[inst.rs2] ) )s.pc += 4
def execute_beq( s, inst ):if s.rf[inst.rs1] == s.rf[inst.rs2]:
s.pc = trim_xlen( s.pc + inst.sb_imm )else:
s.pc += 4

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

6 / 16

Pydgin Framework
Interpreter Loop

State
Encoding

Semantics

def instruction_set_interpreter( memory ):state = State( memory )while True:

PydginFrameworkpc= state.fetch_pc()

inst= memory[ pc ]execute = decode( inst )execute( state, inst )Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator# fetch# decode# execute7 / 16

Pydgin Framework
Interpreter Loop

State
Encoding

Semantics

def instruction_set_interpreter( memory ):state = State( memory )while True:

PydginFrameworkpc
Debug onPythonInterpreter= state.fetch_pc()

inst= memory[ pc ]execute = decode( inst )execute( state, inst )# fetch# decode# execute

100 KIPS

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

7 / 16

The RPython Translation Toolchain
RPython Source
State
Encoding

Semantics

Type InferenceOp�miza�on
PydginFramework

Code Genera�on
Debug onPythonInterpreter

RPythonTranslation
Toolchain

Compila�on

100 KIPS
Compiled Interpreter

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

8 / 16

The RPython Translation Toolchain
RPython Source
State
Encoding

Semantics

Type InferenceOp�miza�on
PydginFramework

Code Genera�on
Debug onPythonInterpreter

RPythonTranslation
Toolchain

Compila�on

100 KIPS
PydginInterpretive
Simulator

Compiled Interpreter

10 MIPS
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

8 / 16

The RPython Translation Toolchain
RPython Source
State
Encoding

Semantics

Type InferenceOp�miza�on

JIT Generator

PydginFramework

Code Genera�on
Debug onPythonInterpreter

RPythonTranslation
Toolchain

Compila�on

100 KIPS
PydginInterpretive
Simulator

Compiled Interpreter with JIT

10 MIPS
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

8 / 16

The RPython Translation Toolchain
RPython Source
State
Encoding

Type Inference

Semantics

Op�miza�on

JIT Generator

PydginFramework

Code Genera�on
Debug onPythonInterpreter

RPythonTranslation
Toolchain

Compila�on

100 KIPS
PydginInterpretive
Simulator

PydginDBT
Simulator

10 MIPS<10 MIPS

Compiled Interpreter with JIT

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

8 / 16

JIT Annotations and Optimizations
Additional RPython JIT hints:
State+ Elidable Instruction Fetch
Encoding+ Elidable Decode

Semantics+ Constant Promotion of PC and Memory+ Word-Based Target Memory

PydginFramework+ JIT Annot.

+ Loop Unrolling in Instruction Semantics+ Virtualizable PC and Statistics+ Increased Trace Limit

Debug onPythonInterpreter

RPythonTranslation
Toolchain

100 KIPS
PydginInterpretive
Simulator

PydginDBT
Simulator

10 MIPS

100+ MIPS
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

SPECINT2006 on ARM
9 / 16

JIT Annotations and Optimizations
23X improvement
over no annotations

Additional RPython JIT hints:
State+ Elidable Instruction Fetch
Encoding+ Elidable Decode

Semantics+ Constant Promotion of PC and Memory+ Word-Based Target Memory

PydginFramework+ JIT Annot.

+ Loop Unrolling in Instruction Semantics+ Virtualizable PC and Statistics+ Increased Trace Limit

Debug onPythonInterpreter

RPythonTranslation
Toolchain

Please see our ISPASS paper
for more details!

100 KIPS
PydginInterpretive
Simulator

PydginDBT
Simulator

10 MIPS

100+ MIPS
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

SPECINT2006 on ARM
9 / 16

Pydgin Performance

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

10 / 16

Pydgin Performance

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

10 / 16

Pydgin Performance

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

10 / 16

Pydgin Performance
Spike is an interpretive
simulator with someadvanced DBT features:- Caching decoded

instructions- PC-indexed dispatch

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

10 / 16

Pydgin Performance
Spike is an interpretive
simulator with someadvanced DBT features:- Caching decoded

instructions- PC-indexed dispatch
RISC-V QEMU port was outof-date at the time of ourdevelopment

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

10 / 16

Pydgin Productivity
RISC-V Foundation

RISC-V encourages ISA extensions.

RISC-V
Specialized
RISC-V
Specialized
RISC-V

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

11 / 16

Pydgin Productivity
RISC-V Foundation

RISC-V encourages ISA extensions.
- Productive Development- Productive Extensibility- Productive Instrumentation

RISC-V
Specialized
RISC-V

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

Specialized
RISC-V

11 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin RISC-V Development

100+ MIPS simulator
after 9 days of development!

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

12 / 16

Pydgin Extensibility
encodings = [# ...
['andi','xxxxxxxxxxxxxxxxx111xxxxx0010011'],['slli','000000xxxxxxxxxxx001xxxxx0010011'],['srli','000000xxxxxxxxxxx101xxxxx0010011'],['srai','010000xxxxxxxxxxx101xxxxx0010011'],['add','0000000xxxxxxxxxx000xxxxx0110011'],# ...
['custom2', 'xxxxxxxxxxxxxxxxx000xxxxx1011011'],
# ...
]

State
Encoding

Semantics

PydginFramework+ JIT Annot.

Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# greatest common divisor semantics
def execute_gcd( s, inst ):PydginDBT
Simulator

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

13 / 16

Pydgin Extensibility
encodings = [# ...
['andi','xxxxxxxxxxxxxxxxx111xxxxx0010011'],['slli','000000xxxxxxxxxxx001xxxxx0010011'],['srli','000000xxxxxxxxxxx101xxxxx0010011'],['srai','010000xxxxxxxxxxx101xxxxx0010011'],['add','0000000xxxxxxxxxx000xxxxx0110011'],# ...
['gcd','xxxxxxxxxxxxxxxxx000xxxxx1011011'],
# ...
]

State
Encoding

Semantics

PydginFramework+ JIT Annot.

Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# greatest common divisor semantics
def execute_gcd( s, inst ):PydginDBT
Simulator

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

13 / 16

Pydgin Extensibility
encodings = [# ...
['andi','xxxxxxxxxxxxxxxxx111xxxxx0010011'],['slli','000000xxxxxxxxxxx001xxxxx0010011'],['srli','000000xxxxxxxxxxx101xxxxx0010011'],['srai','010000xxxxxxxxxxx101xxxxx0010011'],['add','0000000xxxxxxxxxx000xxxxx0110011'],# ...
['gcd','xxxxxxxxxxxxxxxxx000xxxxx1011011'],
# ...
]

State
Encoding

Semantics

PydginFramework+ JIT Annot.

Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# greatest common divisor semantics
def execute_gcd( s, inst ):a, b = s.rf[inst.rs1], s.rf[inst.rs2]
while b:Pydgina, b = b, a%b
DBTs.rf[inst.rd] = a
Simulator
s.pc += 4
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

13 / 16

Pydgin Instrumentation# count number of adds
def execute_addi( s, inst ):s.rf[inst.rd] = s.rf[inst.rs1] + inst.i_imm

State
Encoding

Semantics

s.pc += 4# count misaligned stores
def execute_sw( s, inst ):addr = trim_xlen( s.rf[inst.rs1] + inst.s_imm )PydginFramework+ JIT Annot.

s.mem.write( addr, 4, trim_32( s.rf[inst.rs2] ) )s.pc += 4
Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# record and count all executed loops
def execute_beq( s, inst ):if s.rf[inst.rs1] == s.rf[inst.rs2]:

PydginDBT
Simulator

s.pc = trim_xlen( s.pc + inst.sb_imm )else:
s.pc += 4

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

14 / 16

Pydgin Instrumentation# count number of adds
def execute_addi( s, inst ):s.rf[inst.rd] = s.rf[inst.rs1] + inst.i_imm
s.num_adds += 1
s.pc += 4

State
Encoding

Semantics# count misaligned stores
def execute_sw( s, inst ):addr = trim_xlen( s.rf[inst.rs1] + inst.s_imm )PydginFramework+ JIT Annot.

s.mem.write( addr, 4, trim_32( s.rf[inst.rs2] ) )s.pc += 4
Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# record and count all executed loops
def execute_beq( s, inst ):if s.rf[inst.rs1] == s.rf[inst.rs2]:

PydginDBT
Simulator

s.pc = trim_xlen( s.pc + inst.sb_imm )else:
s.pc += 4

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

14 / 16

Pydgin Instrumentation# count number of adds
def execute_addi( s, inst ):s.rf[inst.rd] = s.rf[inst.rs1] + inst.i_imm
s.num_adds += 1
s.pc += 4

State
Encoding

Semantics# count misaligned stores
def execute_sw( s, inst ):addr = trim_xlen( s.rf[inst.rs1] + inst.s_imm )if addr % 4 != 0: s.num_misaligned += 1
s.mem.write( addr, 4, trim_32( s.rf[inst.rs2] ) )s.pc += 4

PydginFramework+ JIT Annot.

Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# record and count all executed loops
def execute_beq( s, inst ):if s.rf[inst.rs1] == s.rf[inst.rs2]:

PydginDBT
Simulator

s.pc = trim_xlen( s.pc + inst.sb_imm )else:
s.pc += 4

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

14 / 16

Pydgin Instrumentation# count number of adds
def execute_addi( s, inst ):s.rf[inst.rd] = s.rf[inst.rs1] + inst.i_imm
s.num_adds += 1
s.pc += 4

State
Encoding

Semantics# count misaligned stores
def execute_sw( s, inst ):addr = trim_xlen( s.rf[inst.rs1] + inst.s_imm )if addr % 4 != 0: s.num_misaligned += 1
s.mem.write( addr, 4, trim_32( s.rf[inst.rs2] ) )s.pc += 4

PydginFramework+ JIT Annot.

Debug onPythonInterpreter

RPythonTranslation
Toolchain

PydginInterpretive
Simulator# record and count all executed loops
def execute_beq( s, inst ):if s.rf[inst.rs1] == s.rf[inst.rs2]:
old_pc = s.pc
Pydgins.pc = trim_xlen( s.pc + inst.sb_imm )DBT
if s.pc <= old_pc: s.loops[(s.pc, old_pc)] += 1
Simulator
else:
s.pc += 4
Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

14 / 16

Pydgin in Our Research Group• Statistics for software-defined regions

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

15 / 16

Pydgin in Our Research Group• Statistics for software-defined regions• Data-structure specialization experimentation

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

15 / 16

Pydgin in Our Research Group• Statistics for software-defined regions• Data-structure specialization experimentation• Control- and memory-divergence for SIMD

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

15 / 16

Pydgin in Our Research Group• Statistics for software-defined regions• Data-structure specialization experimentation• Control- and memory-divergence for SIMD
• Basic Block Vector generation for SimPoint

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

15 / 16

Pydgin in Our Research Group• Statistics for software-defined regions• Data-structure specialization experimentation• Control- and memory-divergence for SIMD
• Basic Block Vector generation for SimPoint• Analysis of JIT-enabled dynamic language interpreters

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

15 / 16

Conclusions
Pydgin leverages the RPython translation toolchain into highperformance, DBT Instruction Set Simulator.

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

16 / 16

Conclusions
Pydgin leverages the RPython translation toolchain into highperformance, DBT Instruction Set Simulator.
Pydgin provides a succinct architecture description language within
Python to give users a productive development, extension, andinstrumentation experience.

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

16 / 16

Conclusions
Pydgin leverages the RPython translation toolchain into highperformance, DBT Instruction Set Simulator.
Pydgin provides a succinct architecture description language within
Python to give users a productive development, extension, andinstrumentation experience.
Current State: RV64IMAFD (RV64G) Bare-Metal on 64-bit hostPydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

16 / 16

Conclusions
Pydgin leverages the RPython translation toolchain into highperformance, DBT Instruction Set Simulator.
Pydgin provides a succinct architecture description language within
Python to give users a productive development, extension, andinstrumentation experience.
Current State: RV64IMAFD (RV64G) Bare-Metal on 64-bit hostPydginhttps://github.com/cornell-brg/pydgin

Thank you to our sponsors for their support:
NSF, DARPA, and donations from Intel Corporation and
Synopsys, Inc.

Pydgin for RISC-V: A Fast and Productive Instruction-Set Simulator

16 / 16