►
From YouTube: David Lattimore - Running Rust on an FPGA
Description
David has been using Rust since about when version 1.0 was released and has been coming to Rust Sydney meetups since the first one in 2015.
His main Rust project outside of work is the Evcxr REPL and Jupyter kernel. The last couple of years, he's been doing some embedded firmware development using Rust.
A
A
So
you
can
have
a
look
if
you
want
I
should
add
a
quick
disclaimer
that
this
is
my
own
opinions
and
don't
reflect
those
with
my
employer,
a
quick
outline
of
what
I'm
going
to
cover
I'm
going
to
talk
about
what
an
fpga
is.
What
a
soft
CPU
is
talk
about
the
fpga
tool
chain
that
I've
been
using,
which
is
an
open
source
tool
chain,
talk
about
SVD
files
and
SVD
to
rust,
talk
about
writing
a
hardware,
abstraction
layer
and
then
talk
about
interacting
with
your
embedded
code.
A
So,
first
of
all
what
is
an
fpga?
It
stands
for
field,
programmable
gate
array
and
it's
a
collection
of
logic
gates
that
can
be
combined.
That
can
be
programmed
in
the
field.
So
that
means
like,
while
the
device
is
out
in
the
field,
you
can
upload
new
firmware
to
it
and
it
will
reprogram
those
Gates,
so
logic
gates
like
and
Gates
or
Gates
those
kinds
of
things
it
lets.
A
A
Modern
fpgas
consist
of
a
range
of
components,
basic
components
like
lookup
tables,
which
take
several
bits
and
produce
an
output
bit,
so
you
can
use
that
to
create
an
and
gate
or
an
or
gate
or
something
more
more
complicated
flip-flops
which
store
a
single
bit
of
information
until
the
next
clock
cycle,
an
IO
which
lets
you
effectively
read
and
write
the
pins
on
the
fpga,
so
you
can
send
data
and
receive
data
in
addition
to
that,
lots
of
fpgas
have
more
advanced
components
that
you
could
build
from
the
more
basic
components,
so
things
like
Ram,
which
you
can
make
just
using
flip-flops.
A
So
a
soft
CPU
is
a
CPU
that
runs
on
something
like
an
fpga.
It's
often
used
as
risk
five,
since
the
licensing
is
a
lot
easier.
You
don't
have
to
pay
licensing
fees
to
say
arm
or
something
like
that.
If
you
wanted
to
use
the
arm
instruction
set
and
if
you
find
a
bug
in
your
CPU,
you
can
fix
it.
Assuming
you
can
figure
out
what
the
bug
is,
and
you
can
extend
your
cus,
your
CPU
with
custom
instructions
which
we
did
for
our
with
our
project.
A
So
I'll
quickly
Define
what
a
system
on
a
chip
is,
so
you
don't
just
have
a
CPU
running
on
the
soft
on
the
fpga.
You'll
often
have
a
whole
range
of
different
peripherals
like
you
might
have
the
CPU
and
then
an
internal
bus
and
the
ram
might
be
on
the
bus.
So
the
CPU
can
access
the
ram.
Then
you
might
also
have
a
spy
peripheral
which
talks
lets.
You
talk
to
a
spy
flash,
so
your
instructions
might
be.
Your
code
might
be
stored
on
this
by
Flash
and
the
CPU
when
it
wants
to
access.
A
So
it's
an
SOC
or
system
on
a
chip,
so
the
open
source
tool
chain
that
we've
used
is
various
different
components.
One
of
them
is
latex,
which
we
use
for
defining
your
SOC
provides
lots
of
components
that
are
pre-built
things
like
soft
CPUs
buses,
caches,
ethernet
controllers,
flash
storage,
that
kind
of
stuff
and
lets
you
pick,
which
ones
you
want
and
mix
them
together
to
create
an
SOC
amaranth
is
lets.
A
You
write
high
level
code
for
defining
digital
designs,
so
we
used
that
primarily
for
writing
for
implementing
custom
instructions
which
are
then
mixed
into
with
into
latex.
A
So
if
you,
the
electrical
signals
in
the
fpga,
take
time
to
get
from
one
place
to
another,
and
if
you're
running
your
fpga's
clock
at
a
particular
speed,
you
need
to
make
sure
that
the
signals
get
from
from
one
component
to
the
next
before
the
next
clock
cycle,
and
so
next
PNR
handles
optimizing.
The
layout
within
the
fpga,
the
output
from
that
is
then
fed
into
a
tool,
that's
specific
to
your
specific
fpga
in
order
to
produce
a
binary
bit
stream.
This
is
actually
what's
given
to
the
fpga
to
program
it.
A
So,
for
example,
you
might
say
that
an
Ethernet
controller
is
at
a
particular
address
and
it's
got
at
a
particular
offset.
You've
got
a
control
register
and
then
a
couple
of
bits
for
enabling
it
and
setting
speed
have
other
bits
for
sending
and
receiving
data.
That
kind
of
thing
chip
Bend,
is
often
Supply
SBD
files
to
document
their
chips.
The
idea
is
that
this
SVD
is
machine,
readable
and,
and
so
and
handily
for
us
litex
can
generate
SPD
files
for
the
specific
SOC
that
you've
given
it.
A
So
without
SSB
data
rust,
you
might
write
code.
That
looks
like
this.
Where
we've
say,
we've
got
an
LED
that
our
fpga
is
talking
to,
and
we've
defined
a
constant
for
the
memory
address
that
lets.
You
control
that
aspect
that
led
and
now
we
do
a
volatile
read
in
order
to
read
that
memory
needs
to
be
volatile
because
we
need
to
tell
rust
you
can't
remove
this
like
it
has
to
actually
do
the
read
and
then
once
we've
got
that
we
or
it
with
one
in
order
to
set
a
bit
and
then
write
it
back.
A
So
this
is
a
fair
bit
of
code
and
more
more
annoyingly
is
that
it
defines
the
constant
for
Led
address,
which
is
also
defined
in
our
SOC
definition
in
lightx.
So
we
don't
have
that
duplication,
so
SPD
to
rust
generates
this
code
for
us
effectively
and
lets
us
write
something
like
this.
Where
we
we
can
just
set
the
bit,
we
don't
need
to
define
a
constant,
because
it's
all
in
the
generated
code,
it's
still
a
little
bit
high
level
low.
A
Sorry,
it's
a
little
bit
verbose
still,
and
so
the
next
thing
we
do
is
create
a
hardware
abstraction
layer
which
wraps
around
this
low-level
generated
code
and
provides
a
nicer,
a
nicer
interface.
So
we
can
then
just
write
something
like
led1.
turn
on,
and
we
might
also
put
this
behind
a
trait
so
that
we
can
have
two
implementations,
one
for
the
real
hardware
and
one
for
use
in
tests
that
mocks
the
hardware.
A
So
one
thing
I've
found
particularly
useful
when
working
with
embedded
code
on
fpjs
or
otherwise
is
to
have
a
host
side
command
line
tool
that
does
everything
so
builds,
builds
the
firmware
flashes.
The
firmware
to
the
device
gives
you
an
Interactive
command
line
where
you
can
give
commands
to
the
device
lets.
You
see.
Panic
messages
and
debug
print
statements
coming
from
your
code
and
I've
used
a
range
of
different
interfaces
in
order
to
build
such
tools
so
JTAG
serial
I,
squared
C
and
open
OCD,
which
are
different
ways
to
communicate
with
your
with
your
device.
A
So
a
few
resources,
cfu
playground
is
where
we've
done
a
lot
of
the
development
of
custom
instructions,
particularly
working
with
machine
running
machine
learning
models.
So
if
you're
running
a
machine
learning
model-
and
you
want
to
accelerate
it
by
writing
custom
instructions,
that's
well!
That's
good
light
text,
Challenge
and
amaranth,
which
I
mentioned
earlier
and
then
HPS
firmware
is
a
project
in
Chrome
OS,
which
is
the
project
that
we
worked
on.
It's
all
open
source.
So
if
you
want
to
go
and
have
a
look
feel
free,
any
questions.
A
So
the
question
was
for
debug
print
statements:
do
you
just
use
print
line,
or
do
you
use
something
else?
So
most
recently
I've
been
there's
a
few
different
options:
there's
D
format,
which
is
specifically
for
embedded
use
and
avoids
decreasing
your
binary
size.
So
I've
used
that
a
bit
recently,
I've
mostly
just
been
using
the
log
crate
which
does
do
the
formatting
on
the
device,
because
I'm
not
too
constrained
for
space
at
the
moment
and
yeah.
So
then
log
can
have
multiple
backend
outputs.
A
A
So
yeah
the
the
system
is,
does
use
no
STD
and
we
mostly
didn't
use
an
allocator.
The
only
thing
we
actually
needed
an
allocator
for
was
so
that
print.
We
have
some
C
plus
code,
which
is
the
tensorflow
Lite
micro
and
that
needs
to
allocate
in
order
to
print
use
printf.
But
everything
else
doesn't
do
any
allocation.
A
Has
it
different
from
regular
rust
development
on
embedded?
Probably
the
main
thing
is
that
you're,
defining
the
soc
yourself
and
so
there's
no
peripheral
access,
crate
and
probably
know
Hal
already
made
for
you
and
so
you've
got
to
write.
You've
got
to
generate
the
peripheral
access
crate,
which
is
what
SVD
to
rust
generates
and
then
you've
got
to
write
the.
How
yourself?
A
That's
probably
the
main
difference,
and
also
you
can
decide
what
what
bits
you
do
on
the
fpga
versus
what
bits
you
doing
rust
code.
So
you
can
move
that
boundary
a
bit
and
we
have
done
that
a
bit
where
we've
had
had
code,
that's
written
in
Rust
and
we've
decided
to
like
do
a
bit
more
in
the
fpga
logic
and
then
also,
conversely,
take
logic
out
of
the
fpga
and
put
it
into
rust
code.
In
order
to
simplify
the
the
fpga's
programming.
A
So
the
question
was:
how
does
the
custom
instructions
interact
with
the
the
how
sorry
yep
so
the
the
custom
instructions?
A
We
didn't
actually
call
them
directly
from
rust,
because
we
were
using
tensorflow
Lite
micro,
which
is
a
c
plus
code
base,
and
so
the
rust
code
called
tensorflow,
Lite
micro
and
then
the
C
plus
code
called
the
custom
instructions
from
within
its
implementation.
But
we
could
have
called
the
custom
instructions
from
rust
if
we'd
had
a
need
to,
and
it's
basically
just
inline
assembly,
you
just
generate
some
inline
assembly
and
it
yeah.